You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by re...@apache.org on 2026/04/30 15:36:30 UTC
(jackrabbit-oak) branch OAK-12191 created (now 2d85505694)
This is an automated email from the ASF dual-hosted git repository.
reschke pushed a change to branch OAK-12191
in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git
at 2d85505694 OAK-12191: remove elastic-search support from Oak 1.22
This branch includes the following new commits:
new 2d85505694 OAK-12191: remove elastic-search support from Oak 1.22
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(jackrabbit-oak) 01/01: OAK-12191: remove elastic-search support from Oak 1.22
Posted by re...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
reschke pushed a commit to branch OAK-12191
in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git
commit 2d85505694a70deb694d64b3600cf17a0f286d6b
Author: Julian Reschke <re...@apache.org>
AuthorDate: Thu Apr 30 16:35:01 2026 +0100
OAK-12191: remove elastic-search support from Oak 1.22
---
Jenkinsfile | 4 +-
oak-search-elastic/pom.xml | 305 ---------
...DefaultElasticsearchIndexCoordinateFactory.java | 42 --
.../ElasticsearchConnectionFactory.java | 76 ---
.../elasticsearch/ElasticsearchCoordinate.java | 33 -
.../elasticsearch/ElasticsearchCoordinateImpl.java | 140 ----
.../elasticsearch/ElasticsearchIndexConstants.java | 21 -
.../ElasticsearchIndexCoordinate.java | 24 -
.../ElasticsearchIndexCoordinateFactory.java | 23 -
.../ElasticsearchIndexCoordinateImpl.java | 126 ----
.../ElasticsearchIndexDefinition.java | 28 -
.../ElasticsearchIndexProviderService.java | 253 --------
.../elasticsearch/index/ElasticsearchDocument.java | 148 -----
.../index/ElasticsearchDocumentMaker.java | 189 ------
.../index/ElasticsearchIndexEditor.java | 32 -
.../index/ElasticsearchIndexEditorContext.java | 63 --
.../index/ElasticsearchIndexEditorProvider.java | 78 ---
.../index/ElasticsearchIndexWriter.java | 167 -----
.../index/ElasticsearchIndexWriterFactory.java | 36 --
.../elasticsearch/query/ElasticsearchIndex.java | 132 ----
.../query/ElasticsearchIndexNode.java | 68 --
.../query/ElasticsearchIndexProvider.java | 39 --
.../query/ElasticsearchIndexStatistics.java | 65 --
.../query/ElasticsearchResultRowIterator.java | 711 ---------------------
.../elasticsearch/query/ElasticsearchSearcher.java | 57 --
.../util/ElasticsearchIndexDefinitionBuilder.java | 28 -
.../util/TermQueryBuilderFactory.java | 168 -----
pom.xml | 1 -
28 files changed, 2 insertions(+), 3055 deletions(-)
diff --git a/Jenkinsfile b/Jenkinsfile
index 9af84b69d9..9e718ffa09 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -18,9 +18,9 @@
* under the License.
*/
-// schedule oak-jcr:ut,oak-search-elastic,oak-segment-tar,oak-store-document first
+// schedule oak-jcr:ut,oak-segment-tar,oak-store-document first
// because they are longest running modules
-def OAK_MODULES = 'oak-jcr:ut,oak-search-elastic,oak-segment-tar,oak-store-document,oak-api,oak-auth-external,oak-auth-ldap,oak-authorization-cug,oak-authorization-principalbased,oak-benchmarks,oak-blob,oak-blob-cloud,oak-blob-cloud-azure,oak-blob-plugins,oak-commons,oak-core,oak-core-spi,oak-examples,oak-exercise,oak-http,oak-it,oak-it-osgi,oak-jackrabbit-api,oak-jcr:it,oak-lucene,oak-pojosr,oak-query-spi,oak-run,oak-run-commons,oak-search,oak-security-spi,oak-segment-azure,oak-solr-cor [...]
+def OAK_MODULES = 'oak-jcr:ut,oak-segment-tar,oak-store-document,oak-api,oak-auth-external,oak-auth-ldap,oak-authorization-cug,oak-authorization-principalbased,oak-benchmarks,oak-blob,oak-blob-cloud,oak-blob-cloud-azure,oak-blob-plugins,oak-commons,oak-core,oak-core-spi,oak-examples,oak-exercise,oak-http,oak-it,oak-it-osgi,oak-jackrabbit-api,oak-jcr:it,oak-lucene,oak-pojosr,oak-query-spi,oak-run,oak-run-commons,oak-search,oak-security-spi,oak-segment-azure,oak-solr-core,oak-solr-osgi,oak [...]
properties([buildDiscarder(logRotator(artifactDaysToKeepStr: '', artifactNumToKeepStr: '', daysToKeepStr: '', numToKeepStr: '10'))])
diff --git a/oak-search-elastic/pom.xml b/oak-search-elastic/pom.xml
deleted file mode 100644
index 9a4317c8a6..0000000000
--- a/oak-search-elastic/pom.xml
+++ /dev/null
@@ -1,305 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd ">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.apache.jackrabbit</groupId>
- <artifactId>oak-parent</artifactId>
- <version>1.22.25-SNAPSHOT</version>
- <relativePath>../oak-parent/pom.xml</relativePath>
- </parent>
-
- <artifactId>oak-search-elastic</artifactId>
- <name>Oak Elasticsearch</name>
- <packaging>bundle</packaging>
- <description>Oak Elasticsearch integration subproject</description>
-
- <properties>
- <elasticsearch.version>7.1.1</elasticsearch.version>
- <lucene.version>8.0.0</lucene.version>
- </properties>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <configuration>
- <instructions>
- <!-- TODO: of late not embedding this seems to working for locally, BUT it had failed initially. Need to verify-->
- <!-- We need to embed lucene as it's required by various QueryBuilders-->
- <Import-Package>
- <!-- OAK-7182 -->${guava.osgi.import},
- com.codahale.metrics*;version="[3.1, 4)";resolution:=optional,
- *
- </Import-Package>
- <Embed-Dependency>
- lucene-core;inline=true
- elasticsearch-rest-high-level-client;inline=true
- </Embed-Dependency>
- <Export-Package>!*</Export-Package>
- </instructions>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.rat</groupId>
- <artifactId>apache-rat-plugin</artifactId>
- <configuration>
- <excludes>
- <exclude>**/test.rtf</exclude>
- <exclude>**/test.txt</exclude>
- <exclude>**/fvs.csv</exclude>
- </excludes>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
- <dependencies>
- <!-- Optional OSGi dependencies, used only when running within OSGi -->
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.core</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.compendium</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.annotation</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.felix</groupId>
- <artifactId>org.apache.felix.scr.annotations</artifactId>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.apache.jackrabbit</groupId>
- <artifactId>oak-api</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.jackrabbit</groupId>
- <artifactId>oak-core-spi</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.jackrabbit</groupId>
- <artifactId>oak-store-spi</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.jackrabbit</groupId>
- <artifactId>oak-query-spi</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.jackrabbit</groupId>
- <artifactId>oak-core</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.jackrabbit</groupId>
- <artifactId>oak-store-document</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.jackrabbit</groupId>
- <artifactId>oak-search</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- <scope>provided</scope>
- </dependency>
-
- <!-- Logging -->
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
-
- <!-- Nullability annotations -->
- <dependency>
- <groupId>org.jetbrains</groupId>
- <artifactId>annotations</artifactId>
- </dependency>
-
- <!-- Test Dependencies -->
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.elasticsearch.client</groupId>
- <artifactId>elasticsearch-rest-high-level-client</artifactId>
- <version>${elasticsearch.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.lucene</groupId>
- <artifactId>lucene-core</artifactId>
- <version>${lucene.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.jackrabbit</groupId>
- <artifactId>oak-core</artifactId>
- <version>${project.version}</version>
- <classifier>tests</classifier>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.jackrabbit</groupId>
- <artifactId>oak-blob-plugins</artifactId>
- <version>${project.version}</version>
- <classifier>tests</classifier>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.jackrabbit</groupId>
- <artifactId>oak-store-spi</artifactId>
- <version>${project.version}</version>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.jackrabbit</groupId>
- <artifactId>oak-segment-tar</artifactId>
- <version>${project.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.jackrabbit</groupId>
- <artifactId>oak-segment-tar</artifactId>
- <version>${project.version}</version>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.jackrabbit</groupId>
- <artifactId>oak-store-document</artifactId>
- <version>${project.version}</version>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.jackrabbit</groupId>
- <artifactId>oak-jcr</artifactId>
- <version>${project.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.jackrabbit</groupId>
- <artifactId>oak-jcr</artifactId>
- <version>${project.version}</version>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.jackrabbit</groupId>
- <artifactId>oak-commons</artifactId>
- <version>${project.version}</version>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.jackrabbit</groupId>
- <artifactId>jackrabbit-jcr-tests</artifactId>
- <version>${jackrabbit.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.jackrabbit</groupId>
- <artifactId>jackrabbit-core</artifactId>
- <version>${jackrabbit.version}</version>
- <classifier>tests</classifier>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.tika</groupId>
- <artifactId>tika-parsers</artifactId>
- <version>${tika.version}</version>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <groupId>commons-logging</groupId>
- <artifactId>commons-logging</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-log4j12</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.testing.osgi-mock</artifactId>
- </dependency>
- <dependency>
- <groupId>org.hamcrest</groupId>
- <artifactId>hamcrest-all</artifactId>
- <version>1.3</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-core</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>io.dropwizard.metrics</groupId>
- <artifactId>metrics-core</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-exec</artifactId>
- <version>1.3</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>com.google.code.gson</groupId>
- <artifactId>gson</artifactId>
- <version>2.8.0</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.jackrabbit</groupId>
- <artifactId>oak-search</artifactId>
- <classifier>tests</classifier>
- <version>${project.version}</version>
- <scope>test</scope>
- </dependency>
-
-
- </dependencies>
-</project>
diff --git a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/DefaultElasticsearchIndexCoordinateFactory.java b/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/DefaultElasticsearchIndexCoordinateFactory.java
deleted file mode 100644
index 5328b53028..0000000000
--- a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/DefaultElasticsearchIndexCoordinateFactory.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.jackrabbit.oak.plugins.index.elasticsearch;
-
-import org.apache.jackrabbit.oak.plugins.index.search.IndexDefinition;
-import org.apache.jackrabbit.oak.spi.state.NodeState;
-
-import java.util.Map;
-
-public class DefaultElasticsearchIndexCoordinateFactory implements ElasticsearchIndexCoordinateFactory {
- private final Map<String, String> config;
- private final ElasticsearchConnectionFactory factory;
-
- DefaultElasticsearchIndexCoordinateFactory(ElasticsearchConnectionFactory factory, Map<String, String> config) {
- this.factory = factory;
- this.config = config;
- }
-
- @Override
- public ElasticsearchIndexCoordinate getElasticsearchIndexCoordinate(IndexDefinition indexDefinition) {
- ElasticsearchCoordinate esCoord = getElasticsearchCoordinate(indexDefinition.getDefinitionNodeState());
- return new ElasticsearchIndexCoordinateImpl(esCoord, indexDefinition);
- }
-
- private ElasticsearchCoordinate getElasticsearchCoordinate(NodeState indexDefinition) {
- return ElasticsearchCoordinateImpl.construct(factory, indexDefinition, config);
- }
-}
diff --git a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/ElasticsearchConnectionFactory.java b/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/ElasticsearchConnectionFactory.java
deleted file mode 100644
index 1894777e5b..0000000000
--- a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/ElasticsearchConnectionFactory.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.jackrabbit.oak.plugins.index.elasticsearch;
-
-import com.google.common.collect.Maps;
-import org.apache.http.HttpHost;
-import org.elasticsearch.client.RestClient;
-import org.elasticsearch.client.RestHighLevelClient;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-public class ElasticsearchConnectionFactory implements Closeable {
- private static final Logger LOG = LoggerFactory.getLogger(ElasticsearchConnectionFactory.class);
- private final ConcurrentMap<ElasticsearchCoordinate, RestHighLevelClient> clientMap = Maps.newConcurrentMap();
-
- private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
- private final AtomicBoolean isClosed = new AtomicBoolean();
-
- public RestHighLevelClient getConnection(ElasticsearchCoordinate esCoord) {
- lock.readLock().lock();
- try {
- if (isClosed.get()) {
- throw new IllegalStateException("Already closed");
- }
-
- return clientMap.computeIfAbsent(esCoord, elasticsearchCoordinate -> {
- LOG.info("Creating client {}", elasticsearchCoordinate);
- return new RestHighLevelClient(
- RestClient.builder(
- new HttpHost(elasticsearchCoordinate.getHost(),
- elasticsearchCoordinate.getPort(),
- elasticsearchCoordinate.getScheme())
- ));
- });
- } finally {
- lock.readLock().unlock();
- }
- }
-
- @Override
- public void close() {
- lock.writeLock().lock();
- try {
- isClosed.set(true);
- clientMap.values().forEach(restHighLevelClient -> {
- try {
- restHighLevelClient.close();
- } catch (IOException e) {
- LOG.error("Error occurred while closing a connection", e);
- }
- });
- } finally {
- lock.writeLock().unlock();
- }
- }
-}
diff --git a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/ElasticsearchCoordinate.java b/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/ElasticsearchCoordinate.java
deleted file mode 100644
index 97f87b5ef8..0000000000
--- a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/ElasticsearchCoordinate.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.jackrabbit.oak.plugins.index.elasticsearch;
-
-import org.elasticsearch.client.RestHighLevelClient;
-
-public interface ElasticsearchCoordinate {
- String SCHEME_PROP = "elasticsearch.scheme";
- String DEFAULT_SCHEME = "http";
- String HOST_PROP = "elasticsearch.host";
- String DEFAULT_HOST = "127.0.0.1";
- String PORT_PROP = "elasticsearch.port";
- int DEFAULT_PORT = 9200;
-
- RestHighLevelClient getClient();
- String getScheme();
- String getHost();
- int getPort();
-}
diff --git a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/ElasticsearchCoordinateImpl.java b/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/ElasticsearchCoordinateImpl.java
deleted file mode 100644
index 7d99e9b55e..0000000000
--- a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/ElasticsearchCoordinateImpl.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.jackrabbit.oak.plugins.index.elasticsearch;
-
-import com.google.common.base.Objects;
-import org.apache.jackrabbit.oak.plugins.index.search.util.ConfigUtil;
-import org.apache.jackrabbit.oak.spi.state.NodeState;
-import org.elasticsearch.client.RestHighLevelClient;
-
-import java.util.Map;
-
-public class ElasticsearchCoordinateImpl implements ElasticsearchCoordinate {
- private final ElasticsearchConnectionFactory connectionFactory;
- private final String scheme;
- private final String host;
- private final int port;
-
- ElasticsearchCoordinateImpl(ElasticsearchConnectionFactory connectionFactory,
- String scheme, String host, int port) {
- this.connectionFactory = connectionFactory;
- this.scheme = scheme;
- this.host = host;
- this.port = port;
- }
-
- static ElasticsearchCoordinate construct(ElasticsearchConnectionFactory connectionFactory,
- NodeState indexDefn, Map<String, String> configMap) {
- ElasticsearchCoordinate esCoord;
-
- // index defn is at highest prio
- esCoord = readFrom(connectionFactory, indexDefn);
- if (esCoord != null) {
- return esCoord;
- }
-
- // command line comes next
- esCoord = construct(connectionFactory,
- System.getProperty(SCHEME_PROP), System.getProperty(HOST_PROP), Integer.getInteger(PORT_PROP));
- if (esCoord != null) {
- return esCoord;
- }
-
- // config map
- if (configMap != null) {
- Integer port = null;
- try {
- port = Integer.parseInt(configMap.get(PORT_PROP));
- } catch (NumberFormatException nfe) {
- // ignore
- }
- esCoord = construct(connectionFactory, configMap.get(SCHEME_PROP), configMap.get(HOST_PROP), port);
- if (esCoord != null) {
- return esCoord;
- }
- }
-
- return new ElasticsearchCoordinateImpl(connectionFactory, DEFAULT_SCHEME, DEFAULT_HOST, DEFAULT_PORT);
- }
-
- @Override
- public RestHighLevelClient getClient() {
- return connectionFactory.getConnection(this);
- }
-
- @Override
- public String getScheme() {
- return scheme;
- }
-
- @Override
- public String getHost() {
- return host;
- }
-
- @Override
- public int getPort() {
- return port;
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof ElasticsearchCoordinate)) {
- return false;
- }
-
- ElasticsearchCoordinate other = (ElasticsearchCoordinate)o;
- return hashCode() == other.hashCode() // just to have a quicker comparison
- && getScheme().equals(other.getScheme())
- && getHost().equals(other.getHost())
- && getPort() == other.getPort();
- }
-
- @Override
- public int hashCode() {
- return Objects.hashCode(getScheme(), getHost(), getPort());
- }
-
- @Override
- public String toString() {
- return getScheme() + "://" + getHost() + ":" + getPort();
- }
-
- private static ElasticsearchCoordinate readFrom(ElasticsearchConnectionFactory factory, NodeState definition) {
- if (definition == null
- || !definition.hasProperty(SCHEME_PROP)
- || !definition.hasProperty(HOST_PROP)
- || !definition.hasProperty(PORT_PROP)) {
- return null;
- }
-
- String scheme = ConfigUtil.getOptionalValue(definition, SCHEME_PROP, DEFAULT_SCHEME);
- String host = ConfigUtil.getOptionalValue(definition, HOST_PROP, DEFAULT_HOST);
- int port = ConfigUtil.getOptionalValue(definition, PORT_PROP, DEFAULT_PORT);
-
- return new ElasticsearchCoordinateImpl(factory, scheme, host, port);
- }
-
- private static ElasticsearchCoordinate construct(ElasticsearchConnectionFactory factory,
- String scheme, String host, Integer port) {
- if (scheme == null || host == null || port == null) {
- return null;
- }
-
- return new ElasticsearchCoordinateImpl(factory, scheme, host, port);
- }
-}
diff --git a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/ElasticsearchIndexConstants.java b/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/ElasticsearchIndexConstants.java
deleted file mode 100644
index 8e0c5aa3d0..0000000000
--- a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/ElasticsearchIndexConstants.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.jackrabbit.oak.plugins.index.elasticsearch;
-
-public class ElasticsearchIndexConstants {
- public static final String TYPE_ELASTICSEARCH = "elasticsearch";
-}
diff --git a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/ElasticsearchIndexCoordinate.java b/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/ElasticsearchIndexCoordinate.java
deleted file mode 100644
index 7e63aa0d8b..0000000000
--- a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/ElasticsearchIndexCoordinate.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.jackrabbit.oak.plugins.index.elasticsearch;
-
-import org.elasticsearch.client.RestHighLevelClient;
-
-public interface ElasticsearchIndexCoordinate {
- RestHighLevelClient getClient();
- String getEsIndexName();
-}
diff --git a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/ElasticsearchIndexCoordinateFactory.java b/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/ElasticsearchIndexCoordinateFactory.java
deleted file mode 100644
index 5b9626e21a..0000000000
--- a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/ElasticsearchIndexCoordinateFactory.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.jackrabbit.oak.plugins.index.elasticsearch;
-
-import org.apache.jackrabbit.oak.plugins.index.search.IndexDefinition;
-
-public interface ElasticsearchIndexCoordinateFactory {
- ElasticsearchIndexCoordinate getElasticsearchIndexCoordinate(IndexDefinition indexDefinition);
-}
diff --git a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/ElasticsearchIndexCoordinateImpl.java b/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/ElasticsearchIndexCoordinateImpl.java
deleted file mode 100644
index 0889365c38..0000000000
--- a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/ElasticsearchIndexCoordinateImpl.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.jackrabbit.oak.plugins.index.elasticsearch;
-
-import com.google.common.base.Joiner;
-import com.google.common.base.Objects;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import org.apache.jackrabbit.oak.commons.PathUtils;
-import org.apache.jackrabbit.oak.plugins.index.search.IndexDefinition;
-import org.elasticsearch.client.RestHighLevelClient;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-
-import static org.elasticsearch.common.Strings.INVALID_FILENAME_CHARS;
-
-public class ElasticsearchIndexCoordinateImpl implements ElasticsearchIndexCoordinate {
-
- private static final int MAX_NAME_LENGTH = 255;
-
- private final ElasticsearchCoordinate esCoord;
- private final String esIndexName;
-
- ElasticsearchIndexCoordinateImpl(@NotNull ElasticsearchCoordinate esCoord, IndexDefinition indexDefinition) {
- this.esCoord = esCoord;
- esIndexName = getRemoteIndexName(indexDefinition, indexDefinition.getIndexPath());
- }
-
- @Override
- public RestHighLevelClient getClient() {
- return esCoord.getClient();
- }
-
- @Override
- public String getEsIndexName() {
- return esIndexName;
- }
-
- @Override
- public int hashCode() {
- return Objects.hashCode(esCoord, esIndexName);
- }
-
- @Override
- public boolean equals(Object o) {
- if (! (o instanceof ElasticsearchIndexCoordinateImpl)) {
- return false;
- }
- ElasticsearchIndexCoordinateImpl other = (ElasticsearchIndexCoordinateImpl)o;
- return hashCode() == other.hashCode()
- && esCoord.equals(other.esCoord)
- && esIndexName.equals(other.esIndexName);
- }
-
- private String getRemoteIndexName(IndexDefinition definition, String indexPath) {
- String suffix = definition.getUniqueId();
-
- if (suffix == null) {
- suffix = String.valueOf(definition.getReindexCount());
- }
-
- return getESSafeIndexName(indexPath + "-" + suffix);
- }
-
- /**
- * <ul>
- * <li>abc -> abc</li>
- * <li>xy:abc -> xyabc</li>
- * <li>/oak:index/abc -> abc</li>
- * </ul>
- *
- * The resulting file name would be truncated to MAX_NAME_LENGTH
- */
- private static String getESSafeIndexName(String indexPath) {
- List<String> elements = Lists.newArrayList(PathUtils.elements(indexPath));
- Collections.reverse(elements);
- List<String> result = Lists.newArrayListWithCapacity(2);
-
- //Max 3 nodeNames including oak:index which is the immediate parent for any indexPath
- for (String e : Iterables.limit(elements, 3)) {
- if ("oak:index".equals(e)) {
- continue;
- }
-
- result.add(getESSafeName(e));
- }
-
- Collections.reverse(result);
- String name = Joiner.on('_').join(result);
- if (name.length() > MAX_NAME_LENGTH){
- name = name.substring(0, MAX_NAME_LENGTH);
- }
- return name;
- }
-
- /**
- * Convert {@code e} to Elasticsearch safe index name.
- * Ref: https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-create-index.html
- */
- private static String getESSafeName(String suggestedIndexName) {
- String invalidCharsRegex = Pattern.quote(INVALID_FILENAME_CHARS
- .stream()
- .map(Object::toString)
- .collect(Collectors.joining("")));
- return suggestedIndexName.replaceAll(invalidCharsRegex, "").toLowerCase();
- }
-
-}
diff --git a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/ElasticsearchIndexDefinition.java b/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/ElasticsearchIndexDefinition.java
deleted file mode 100644
index 1eeade244f..0000000000
--- a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/ElasticsearchIndexDefinition.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.jackrabbit.oak.plugins.index.elasticsearch;
-
-import org.apache.jackrabbit.oak.plugins.index.search.IndexDefinition;
-import org.apache.jackrabbit.oak.spi.state.NodeState;
-
-public class ElasticsearchIndexDefinition extends IndexDefinition {
- public ElasticsearchIndexDefinition(NodeState root, NodeState defn, String indexPath) {
- super(root, getIndexDefinitionState(defn), determineIndexFormatVersion(defn), determineUniqueId(defn), indexPath);
- }
-}
diff --git a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/ElasticsearchIndexProviderService.java b/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/ElasticsearchIndexProviderService.java
deleted file mode 100644
index fd6a2a969f..0000000000
--- a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/ElasticsearchIndexProviderService.java
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.jackrabbit.oak.plugins.index.elasticsearch;
-
-import com.google.common.base.Strings;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import org.apache.commons.io.FilenameUtils;
-import org.apache.felix.scr.annotations.*;
-import org.apache.jackrabbit.oak.api.jmx.CacheStatsMBean;
-import org.apache.jackrabbit.oak.cache.CacheStats;
-import org.apache.jackrabbit.oak.commons.IOUtils;
-import org.apache.jackrabbit.oak.commons.PropertiesUtil;
-import org.apache.jackrabbit.oak.osgi.OsgiWhiteboard;
-import org.apache.jackrabbit.oak.plugins.index.IndexEditorProvider;
-import org.apache.jackrabbit.oak.plugins.index.elasticsearch.index.ElasticsearchIndexEditorProvider;
-import org.apache.jackrabbit.oak.plugins.index.elasticsearch.query.ElasticsearchIndexProvider;
-import org.apache.jackrabbit.oak.plugins.index.fulltext.PreExtractedTextProvider;
-import org.apache.jackrabbit.oak.plugins.index.search.ExtractedTextCache;
-import org.apache.jackrabbit.oak.plugins.index.search.TextExtractionStatsMBean;
-import org.apache.jackrabbit.oak.spi.whiteboard.Registration;
-import org.apache.jackrabbit.oak.spi.whiteboard.Whiteboard;
-import org.apache.jackrabbit.oak.stats.StatisticsProvider;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.util.Dictionary;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Map;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.apache.commons.io.FileUtils.ONE_MB;
-import static org.apache.jackrabbit.oak.spi.whiteboard.WhiteboardUtils.registerMBean;
-
-@Component(metatype = true, label = "Apache Jackrabbit Oak ElasticsearchIndexProvider")
-public class ElasticsearchIndexProviderService {
-
- private static final Logger LOG = LoggerFactory.getLogger(ElasticsearchIndexProviderService.class);
-
- private static final String REPOSITORY_HOME = "repository.home";
-
- private static final int PROP_EXTRACTED_TEXT_CACHE_SIZE_DEFAULT = 20;
- @Property(
- intValue = PROP_EXTRACTED_TEXT_CACHE_SIZE_DEFAULT,
- label = "Extracted text cache size (MB)",
- description = "Cache size in MB for caching extracted text for some time. When set to 0 then " +
- "cache would be disabled"
- )
- private static final String PROP_EXTRACTED_TEXT_CACHE_SIZE = "extractedTextCacheSizeInMB";
-
- private static final int PROP_EXTRACTED_TEXT_CACHE_EXPIRY_DEFAULT = 300;
- @Property(
- intValue = PROP_EXTRACTED_TEXT_CACHE_EXPIRY_DEFAULT,
- label = "Extracted text cache expiry (secs)",
- description = "Time in seconds for which the extracted text would be cached in memory"
- )
- private static final String PROP_EXTRACTED_TEXT_CACHE_EXPIRY = "extractedTextCacheExpiryInSecs";
-
- private static final boolean PROP_PRE_EXTRACTED_TEXT_ALWAYS_USE_DEFAULT = false;
- @Property(
- boolValue = PROP_PRE_EXTRACTED_TEXT_ALWAYS_USE_DEFAULT,
- label = "Always use pre-extracted text cache",
- description = "By default pre extracted text cache would only be used for reindex case. If this setting " +
- "is enabled then it would also be used in normal incremental indexing"
- )
- private static final String PROP_PRE_EXTRACTED_TEXT_ALWAYS_USE = "alwaysUsePreExtractedCache";
-
- private static final String PROP_ELASTICSEARCH_SCHEME_DEFAULT = "http";
-// @Property(
-// value = PROP_ELASTICSEARCH_SCHEME_DEFAULT,
-// label = "Elasticsearch connection scheme"
-// )
- private static final String PROP_ELASTICSEARCH_SCHEME = "elasticsearch.scheme";
-
- private static final String PROP_ELASTICSEARCH_HOST_DEFAULT = "localhost";
-// @Property(
-// value = PROP_ELASTICSEARCH_HOST_DEFAULT,
-// label = "Elasticsearch connection host"
-// )
- private static final String PROP_ELASTICSEARCH_HOST = "elasticsearch.host";
-
- private static final int PROP_ELASTICSEARCH_PORT_DEFAULT = 9200;
-// @Property(
-// intValue = PROP_ELASTICSEARCH_PORT_DEFAULT,
-// label = "Elasticsearch connection port"
-// )
- private static final String PROP_ELASTICSEARCH_PORT = "elasticsearch.port";
-
- @Property(
- label = "Local text extraction cache path",
- description = "Local file system path where text extraction cache stores/load entries to recover from timed out operation"
- )
- private static final String PROP_LOCAL_TEXT_EXTRACTION_DIR = "localTextExtractionDir";
-
- @Reference
- private StatisticsProvider statisticsProvider;
-
- @Reference(policy = ReferencePolicy.DYNAMIC,
- cardinality = ReferenceCardinality.OPTIONAL_UNARY,
- policyOption = ReferencePolicyOption.GREEDY
- )
- private volatile PreExtractedTextProvider extractedTextProvider;
-
- private ExtractedTextCache extractedTextCache;
-
- private ElasticsearchConnectionFactory connectionFactory = null;
-
- private final List<ServiceRegistration> regs = Lists.newArrayList();
- private final List<Registration> oakRegs = Lists.newArrayList();
-
- private Whiteboard whiteboard;
- private File textExtractionDir;
-
- @Activate
- private void activate(BundleContext bundleContext, Map<String, ?> config) {
- whiteboard = new OsgiWhiteboard(bundleContext);
-
- initializeTextExtractionDir(bundleContext, config);
- initializeExtractedTextCache(config, statisticsProvider);
-
- connectionFactory = new ElasticsearchConnectionFactory();
- ElasticsearchIndexCoordinateFactory esIndexCoordFactory = getElasticsearchIndexCoordinateFactory(config);
-
- registerIndexProvider(bundleContext, esIndexCoordFactory);
- registerIndexEditor(bundleContext, esIndexCoordFactory);
- }
-
- @Deactivate
- private void deactivate() {
- for (ServiceRegistration reg : regs) {
- reg.unregister();
- }
-
- for (Registration reg : oakRegs) {
- reg.unregister();
- }
-
- IOUtils.closeQuietly(connectionFactory);
- connectionFactory = null;
-
- if (extractedTextCache != null) {
- extractedTextCache.close();
- }
- }
-
- private void registerIndexProvider(BundleContext bundleContext, ElasticsearchIndexCoordinateFactory esIndexCoordFactory) {
- ElasticsearchIndexProvider indexProvider = new ElasticsearchIndexProvider(esIndexCoordFactory);
-
- Dictionary<String, Object> props = new Hashtable<>();
- props.put("type", ElasticsearchIndexConstants.TYPE_ELASTICSEARCH);
- regs.add(bundleContext.registerService(IndexEditorProvider.class.getName(), indexProvider, props));
- }
-
- private void registerIndexEditor(BundleContext bundleContext, ElasticsearchIndexCoordinateFactory esIndexCoordFactory) {
- ElasticsearchIndexEditorProvider editorProvider = new ElasticsearchIndexEditorProvider(esIndexCoordFactory, extractedTextCache);
-
- Dictionary<String, Object> props = new Hashtable<>();
- props.put("type", ElasticsearchIndexConstants.TYPE_ELASTICSEARCH);
- regs.add(bundleContext.registerService(IndexEditorProvider.class.getName(), editorProvider, props));
- oakRegs.add(registerMBean(whiteboard,
- TextExtractionStatsMBean.class,
- editorProvider.getExtractedTextCache().getStatsMBean(),
- TextExtractionStatsMBean.TYPE,
- "TextExtraction statistics"));
- }
-
- private void initializeExtractedTextCache(Map<String, ?> config, StatisticsProvider statisticsProvider) {
- int cacheSizeInMB = PropertiesUtil.toInteger(config.get(PROP_EXTRACTED_TEXT_CACHE_SIZE),
- PROP_EXTRACTED_TEXT_CACHE_SIZE_DEFAULT);
- int cacheExpiryInSecs = PropertiesUtil.toInteger(config.get(PROP_EXTRACTED_TEXT_CACHE_EXPIRY),
- PROP_EXTRACTED_TEXT_CACHE_EXPIRY_DEFAULT);
- boolean alwaysUsePreExtractedCache = PropertiesUtil.toBoolean(config.get(PROP_PRE_EXTRACTED_TEXT_ALWAYS_USE),
- PROP_PRE_EXTRACTED_TEXT_ALWAYS_USE_DEFAULT);
-
- extractedTextCache = new ExtractedTextCache(
- cacheSizeInMB * ONE_MB,
- cacheExpiryInSecs,
- alwaysUsePreExtractedCache,
- textExtractionDir,
- statisticsProvider);
- if (extractedTextProvider != null){
- registerExtractedTextProvider(extractedTextProvider);
- }
- CacheStats stats = extractedTextCache.getCacheStats();
- if (stats != null){
- oakRegs.add(registerMBean(whiteboard,
- CacheStatsMBean.class, stats,
- CacheStatsMBean.TYPE, stats.getName()));
- LOG.info("Extracted text caching enabled with maxSize {} MB, expiry time {} secs",
- cacheSizeInMB, cacheExpiryInSecs);
- }
- }
-
- void initializeTextExtractionDir(BundleContext bundleContext, Map<String, ?> config) {
- String textExtractionDir = PropertiesUtil.toString(config.get(PROP_LOCAL_TEXT_EXTRACTION_DIR), null);
- if (Strings.isNullOrEmpty(textExtractionDir)) {
- String repoHome = bundleContext.getProperty(REPOSITORY_HOME);
- if (repoHome != null){
- textExtractionDir = FilenameUtils.concat(repoHome, "index");
- }
- }
-
- checkNotNull(textExtractionDir, "Text extraction directory cannot be determined as neither " +
- "directory path [%s] nor repository home [%s] defined", PROP_LOCAL_TEXT_EXTRACTION_DIR, REPOSITORY_HOME);
-
- this.textExtractionDir = new File(textExtractionDir);
- }
-
- private void registerExtractedTextProvider(PreExtractedTextProvider provider){
- if (extractedTextCache != null){
- if (provider != null){
- String usage = extractedTextCache.isAlwaysUsePreExtractedCache() ?
- "always" : "only during reindexing phase";
- LOG.info("Registering PreExtractedTextProvider {} with extracted text cache. " +
- "It would be used {}", provider, usage);
- } else {
- LOG.info("Unregistering PreExtractedTextProvider with extracted text cache");
- }
- extractedTextCache.setExtractedTextProvider(provider);
- }
- }
-
- private ElasticsearchIndexCoordinateFactory getElasticsearchIndexCoordinateFactory(Map<String, ?> config) {
- ElasticsearchIndexCoordinateFactory esIndexCoordFactory;
- Map<String, String> esCfg = Maps.newHashMap();
- esCfg.put(ElasticsearchCoordinate.SCHEME_PROP,
- PropertiesUtil.toString(config.get(PROP_ELASTICSEARCH_SCHEME), PROP_ELASTICSEARCH_SCHEME_DEFAULT));
- esCfg.put(ElasticsearchCoordinate.HOST_PROP,
- PropertiesUtil.toString(config.get(PROP_ELASTICSEARCH_HOST), PROP_ELASTICSEARCH_HOST_DEFAULT));
- esCfg.put(ElasticsearchCoordinate.PORT_PROP, String.valueOf(
- PropertiesUtil.toInteger(config.get(PROP_ELASTICSEARCH_PORT), PROP_ELASTICSEARCH_PORT_DEFAULT)));
- esIndexCoordFactory = new DefaultElasticsearchIndexCoordinateFactory(connectionFactory, esCfg);
- return esIndexCoordFactory;
- }
-}
diff --git a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/index/ElasticsearchDocument.java b/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/index/ElasticsearchDocument.java
deleted file mode 100644
index ea982c8ecb..0000000000
--- a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/index/ElasticsearchDocument.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.jackrabbit.oak.plugins.index.elasticsearch.index;
-
-import com.google.common.collect.Maps;
-import org.apache.jackrabbit.oak.commons.PathUtils;
-import org.apache.jackrabbit.oak.plugins.index.search.FieldNames;
-import org.elasticsearch.common.Strings;
-import org.elasticsearch.common.xcontent.XContentBuilder;
-import org.elasticsearch.common.xcontent.XContentFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
-import java.util.List;
-import java.util.Map;
-
-import static com.google.common.collect.Lists.newArrayList;
-
-public class ElasticsearchDocument {
- private static final Logger LOG = LoggerFactory.getLogger(ElasticsearchDocument.class);
-
- // id should only be useful for logging (at least as of now)
- private final String path;
-
- private final String id;
- private final List<String> fulltext;
- private final List<String> suggest;
- private final List<String> notNullProps;
- private final List<String> nullProps;
- private final Map<String, Object> properties;
-
- ElasticsearchDocument(String path) {
- this.path = path;
- String id = null;
- try {
- id = pathToId(path);
- } catch (UnsupportedEncodingException e) {
- LOG.warn("Couldn't encode {} as ES id", path);
- }
- this.id = id;
- this.fulltext = newArrayList();
- this.suggest = newArrayList();
- this.notNullProps = newArrayList();
- this.nullProps = newArrayList();
- this.properties = Maps.newHashMap();
- }
-
- void addFulltext(String value) {
- fulltext.add(value);
- }
-
- void addFulltextRelative(String path, String value) {
- addProperty(FieldNames.createFulltextFieldName(path), value);
- }
-
- void addSuggest(String value) {
- suggest.add(value);
- }
-
- void notNullProp(String propName) {
- notNullProps.add(propName);
- }
-
- void nullProp(String propName) {
- nullProps.add(propName);
- }
-
- // ES for String values (that are not interpreted as date or numbers etc) would analyze in the same
- // field and would index a sub-field "keyword" for non-analyzed value.
- // ref: https://www.elastic.co/blog/strings-are-dead-long-live-strings
- // (interpretation of date etc: https://www.elastic.co/guide/en/elasticsearch/reference/current/dynamic-field-mapping.html)
- void addProperty(String fieldName, Object value) {
- properties.put(fieldName, value);
- }
-
- void indexAncestors(String path) {
- String parPath = PathUtils.getParentPath(path);
- int depth = PathUtils.getDepth(path);
-
- // TODO: remember that mapping must be configured with
- // https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-pathhierarchy-tokenizer.html
- addProperty(FieldNames.ANCESTORS, parPath);
- addProperty(FieldNames.PATH_DEPTH, depth);
- }
-
- String getId() {
- return id;
- }
-
- public String build() {
- String ret = null;
- try {
- XContentBuilder builder = XContentFactory.jsonBuilder();
- builder.startObject();
- if (fulltext.size() > 0) {
- builder.field(FieldNames.FULLTEXT, fulltext);
- }
- if (suggest.size() > 0) {
- builder.startObject(FieldNames.SUGGEST).field("input", suggest).endObject();
- }
- if (notNullProps.size() > 0) {
- builder.field(FieldNames.NOT_NULL_PROPS, notNullProps);
- }
- if (nullProps.size() > 0) {
- builder.field(FieldNames.NULL_PROPS, nullProps);
- }
- for (Map.Entry<String, Object> prop : properties.entrySet()) {
- builder.field(prop.getKey(), prop.getValue());
- }
- builder.endObject();
-
- ret = Strings.toString(builder);
- } catch (IOException e) {
- LOG.error("Error serializing document - id: {}, properties: {}, fulltext: {}, suggest: {}, " +
- "notNullProps: {}, nullProps: {}",
- path, properties, fulltext, suggest, notNullProps, nullProps,
- e);
- }
-
- return ret;
- }
-
- @Override
- public String toString() {
- return build();
- }
-
- public static String pathToId(String path) throws UnsupportedEncodingException {
- return URLEncoder.encode(path, "UTF-8");
- }
-}
diff --git a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/index/ElasticsearchDocumentMaker.java b/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/index/ElasticsearchDocumentMaker.java
deleted file mode 100644
index b1b14406a6..0000000000
--- a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/index/ElasticsearchDocumentMaker.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.jackrabbit.oak.plugins.index.elasticsearch.index;
-
-import org.apache.jackrabbit.oak.api.Blob;
-import org.apache.jackrabbit.oak.api.PropertyState;
-import org.apache.jackrabbit.oak.api.Type;
-import org.apache.jackrabbit.oak.plugins.index.search.Aggregate;
-import org.apache.jackrabbit.oak.plugins.index.search.FieldNames;
-import org.apache.jackrabbit.oak.plugins.index.search.IndexDefinition;
-import org.apache.jackrabbit.oak.plugins.index.search.PropertyDefinition;
-import org.apache.jackrabbit.oak.plugins.index.search.spi.binary.FulltextBinaryTextExtractor;
-import org.apache.jackrabbit.oak.plugins.index.search.spi.editor.FulltextDocumentMaker;
-import org.apache.jackrabbit.oak.spi.state.NodeState;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.io.IOException;
-import java.util.List;
-
-public class ElasticsearchDocumentMaker extends FulltextDocumentMaker<ElasticsearchDocument> {
-
- ElasticsearchDocumentMaker(@Nullable FulltextBinaryTextExtractor textExtractor,
- @NotNull IndexDefinition definition,
- IndexDefinition.IndexingRule indexingRule, @NotNull String path) {
- super(textExtractor, definition, indexingRule, path);
- }
-
- @Override
- protected ElasticsearchDocument initDoc() {
- return new ElasticsearchDocument(path);
- }
-
- @Override
- protected ElasticsearchDocument finalizeDoc(ElasticsearchDocument doc, boolean dirty, boolean facet) throws IOException {
- if (doc.getId() == null) {
- throw new IOException("Couldn't generate id for doc - (More details during initDoc)" + doc);
- }
- return doc;
- }
-
- // TODO: needed only for oak-lucene. Should be removed from oak-search
- @Override
- protected boolean isFacetingEnabled() {
- return false;
- }
-
- @Override
- protected boolean indexTypeOrderedFields(ElasticsearchDocument doc, String pname, int tag, PropertyState property, PropertyDefinition pd) {
- // TODO: check the conjecture below
- // ES doesn't seem to require special mapping to sort so we don't need to add anything
- return false;
- }
-
- @Override
- protected boolean addBinary(ElasticsearchDocument doc, String path, List<String> binaryValues) {
- boolean added = false;
- for (String binaryValue : binaryValues) {
- if (path != null) {
- doc.addFulltextRelative(path, binaryValue);
- } else {
- doc.addFulltext(binaryValue);
- }
-
- added = true;
- }
-
- return added;
- }
-
- @Override
- protected boolean indexFacetProperty(ElasticsearchDocument doc, int tag, PropertyState property, String pname) {
- // faceting on ES works automatically for keyword (propertyIndex) and subsequently query params.
- // We we don't need to add anything.
- // https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-terms-aggregation.html
- return false;
- }
-
- @Override
- protected void indexAnalyzedProperty(ElasticsearchDocument doc, String pname, String value, PropertyDefinition pd) {
- doc.addProperty(FieldNames.createAnalyzedFieldName(pname), value);
- }
-
- @Override
- protected void indexSuggestValue(ElasticsearchDocument doc, String value) {
- doc.addSuggest(value);
- }
-
- @Override
- protected void indexSpellcheckValue(ElasticsearchDocument doc, String value) {
- // TODO: Figure out how to do spellcheck with ES (interwebs seems to say that it should be simple
- // and don't need anything extra in indexed document
- }
-
- @Override
- protected void indexFulltextValue(ElasticsearchDocument doc, String value) {
- // Note: diversion from lucene impl - here we are storing even these cases and not just binary
- doc.addFulltext(value);
- }
-
- @Override
- protected void indexTypedProperty(ElasticsearchDocument doc, PropertyState property, String pname, PropertyDefinition pd, int i) {
- int tag = property.getType().tag();
-
- Object f;
- if (tag == Type.LONG.tag()) {
- f = property.getValue(Type.LONG, i);
- } else if (tag == Type.DATE.tag()) {
- f = property.getValue(Type.DATE, i);
- } else if (tag == Type.DOUBLE.tag()) {
- f = property.getValue(Type.DOUBLE, i);
- } else if (tag == Type.BOOLEAN.tag()) {
- f = property.getValue(Type.BOOLEAN, i).toString();
- } else {
- f = property.getValue(Type.STRING, i);
- }
-
- doc.addProperty(pname, f);
- }
-
- @Override
- protected void indexAncestors(ElasticsearchDocument doc, String path) {
- doc.indexAncestors(path);
- }
-
- @Override
- protected void indexNotNullProperty(ElasticsearchDocument doc, PropertyDefinition pd) {
- doc.notNullProp(pd.name);
- }
-
- @Override
- protected void indexNullProperty(ElasticsearchDocument doc, PropertyDefinition pd) {
- doc.nullProp(pd.name);
- }
-
- @Override
- protected void indexAggregateValue(ElasticsearchDocument doc, Aggregate.NodeIncludeResult result, String value, PropertyDefinition pd) {
- if (result.isRelativeNode()) {
- doc.addFulltextRelative(result.rootIncludePath, value);
- } else {
- doc.addFulltext(value);
- }
- }
-
- @Override
- protected void indexNodeName(ElasticsearchDocument doc, String value) {
- doc.addProperty(FieldNames.NODE_NAME, value);
- }
-
- @Override
- protected boolean indexSimilarityTag(ElasticsearchDocument doc, PropertyState property) {
- // TODO : not implemented
- return false;
- }
-
- @Override
- protected void indexSimilarityBinaries(ElasticsearchDocument doc, PropertyDefinition pd, Blob blob) throws IOException {
- // TODO : not implemented
- // see https://www.elastic.co/blog/text-similarity-search-with-vectors-in-elasticsearch
- // see https://www.elastic.co/guide/en/elasticsearch/reference/current/dense-vector.html
- }
-
- @Override
- protected void indexSimilarityStrings(ElasticsearchDocument doc, PropertyDefinition pd, String value) throws IOException {
- // TODO : not implemented
- }
-
- @Override
- protected boolean augmentCustomFields(String path, ElasticsearchDocument doc, NodeState document) {
- // TODO : not implemented
- return false;
- }
-}
diff --git a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/index/ElasticsearchIndexEditor.java b/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/index/ElasticsearchIndexEditor.java
deleted file mode 100644
index 9ff586e787..0000000000
--- a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/index/ElasticsearchIndexEditor.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.jackrabbit.oak.plugins.index.elasticsearch.index;
-
-import org.apache.jackrabbit.oak.api.CommitFailedException;
-import org.apache.jackrabbit.oak.plugins.index.IndexEditor;
-import org.apache.jackrabbit.oak.plugins.index.search.spi.editor.FulltextIndexEditor;
-import org.apache.jackrabbit.oak.plugins.index.search.spi.editor.FulltextIndexEditorContext;
-
-/**
- * {@link IndexEditor} implementation that is responsible for keeping the
- * corresponding Elasticsearch index up to date
- */
-public class ElasticsearchIndexEditor extends FulltextIndexEditor<ElasticsearchDocument> {
- ElasticsearchIndexEditor(FulltextIndexEditorContext<ElasticsearchDocument> context) throws CommitFailedException {
- super(context);
- }
-}
diff --git a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/index/ElasticsearchIndexEditorContext.java b/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/index/ElasticsearchIndexEditorContext.java
deleted file mode 100644
index ea04cab133..0000000000
--- a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/index/ElasticsearchIndexEditorContext.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.jackrabbit.oak.plugins.index.elasticsearch.index;
-
-import org.apache.jackrabbit.oak.plugins.index.IndexUpdateCallback;
-import org.apache.jackrabbit.oak.plugins.index.IndexingContext;
-import org.apache.jackrabbit.oak.plugins.index.search.ExtractedTextCache;
-import org.apache.jackrabbit.oak.plugins.index.search.IndexDefinition;
-import org.apache.jackrabbit.oak.plugins.index.search.spi.editor.DocumentMaker;
-import org.apache.jackrabbit.oak.plugins.index.search.spi.editor.FulltextIndexEditorContext;
-import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
-import org.apache.jackrabbit.oak.spi.state.NodeState;
-import org.jetbrains.annotations.Nullable;
-
-public class ElasticsearchIndexEditorContext extends FulltextIndexEditorContext<ElasticsearchDocument> {
- ElasticsearchIndexEditorContext(NodeState root,
- NodeBuilder definition, @Nullable IndexDefinition indexDefinition,
- IndexUpdateCallback updateCallback,
- ElasticsearchIndexWriterFactory indexWriterFactory,
- ExtractedTextCache extractedTextCache,
- IndexingContext indexingContext,
- boolean asyncIndexing) {
- super(root, definition, indexDefinition, updateCallback, indexWriterFactory, extractedTextCache, indexingContext, asyncIndexing);
- }
-
- @Override
- public IndexDefinition.Builder newDefinitionBuilder() {
- return new IndexDefinition.Builder();
- }
-
- @Override
- public DocumentMaker<ElasticsearchDocument> newDocumentMaker(IndexDefinition.IndexingRule rule, String path) {
- return new ElasticsearchDocumentMaker(getTextExtractor(), getDefinition(), rule, path);
- }
-
- @Override
- public void enableReindexMode() {
- super.enableReindexMode();
-
- // Now, that index definition _might_ have been migrated by super call, it would be ok to
- // get writer and provision index settings and mappings
- getWriter().setProvisioningRequired();
- }
-
- @Override
- public ElasticsearchIndexWriter getWriter() {
- return (ElasticsearchIndexWriter)super.getWriter();
- }
-}
\ No newline at end of file
diff --git a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/index/ElasticsearchIndexEditorProvider.java b/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/index/ElasticsearchIndexEditorProvider.java
deleted file mode 100644
index b73bd05455..0000000000
--- a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/index/ElasticsearchIndexEditorProvider.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.jackrabbit.oak.plugins.index.elasticsearch.index;
-
-import org.apache.jackrabbit.oak.api.CommitFailedException;
-import org.apache.jackrabbit.oak.plugins.index.ContextAwareCallback;
-import org.apache.jackrabbit.oak.plugins.index.IndexEditorProvider;
-import org.apache.jackrabbit.oak.plugins.index.IndexUpdateCallback;
-import org.apache.jackrabbit.oak.plugins.index.IndexingContext;
-import org.apache.jackrabbit.oak.plugins.index.elasticsearch.ElasticsearchIndexCoordinateFactory;
-import org.apache.jackrabbit.oak.plugins.index.elasticsearch.ElasticsearchIndexDefinition;
-import org.apache.jackrabbit.oak.plugins.index.search.ExtractedTextCache;
-import org.apache.jackrabbit.oak.spi.commit.Editor;
-import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
-import org.apache.jackrabbit.oak.spi.state.NodeState;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static org.apache.jackrabbit.oak.plugins.index.elasticsearch.ElasticsearchIndexConstants.TYPE_ELASTICSEARCH;
-
-public class ElasticsearchIndexEditorProvider implements IndexEditorProvider {
-
- private final ElasticsearchIndexCoordinateFactory esIndexCoordFactory;
- private final ExtractedTextCache extractedTextCache;
-
- public ElasticsearchIndexEditorProvider(@NotNull ElasticsearchIndexCoordinateFactory esIndexCoordFactory,
- ExtractedTextCache extractedTextCache) {
- this.esIndexCoordFactory = esIndexCoordFactory;
- this.extractedTextCache = extractedTextCache != null ? extractedTextCache : new ExtractedTextCache(0, 0);
- }
-
- @Override
- public @Nullable Editor getIndexEditor(@NotNull String type,
- @NotNull NodeBuilder definition, @NotNull NodeState root,
- @NotNull IndexUpdateCallback callback) throws CommitFailedException {
- if (TYPE_ELASTICSEARCH.equals(type)) {
- checkArgument(callback instanceof ContextAwareCallback, "callback instance not of type " +
- "ContextAwareCallback [%s]", callback);
- IndexingContext indexingContext = ((ContextAwareCallback)callback).getIndexingContext();
-
- String indexPath = indexingContext.getIndexPath();
- ElasticsearchIndexDefinition indexDefinition =
- new ElasticsearchIndexDefinition(root, definition.getNodeState(), indexPath);
-
- ElasticsearchIndexWriterFactory writerFactory = new ElasticsearchIndexWriterFactory(esIndexCoordFactory);
-
- ElasticsearchIndexEditorContext context = new ElasticsearchIndexEditorContext(root,
- definition, indexDefinition,
- callback,
- writerFactory,
- extractedTextCache,
- indexingContext,
- true);
-
- return new ElasticsearchIndexEditor(context);
- }
- return null;
- }
-
- public ExtractedTextCache getExtractedTextCache() {
- return extractedTextCache;
- }
-}
diff --git a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/index/ElasticsearchIndexWriter.java b/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/index/ElasticsearchIndexWriter.java
deleted file mode 100644
index 348c2a516a..0000000000
--- a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/index/ElasticsearchIndexWriter.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.jackrabbit.oak.plugins.index.elasticsearch.index;
-
-import org.apache.jackrabbit.oak.plugins.index.elasticsearch.ElasticsearchIndexCoordinateFactory;
-import org.apache.jackrabbit.oak.plugins.index.elasticsearch.ElasticsearchIndexCoordinate;
-import org.apache.jackrabbit.oak.plugins.index.search.FieldNames;
-import org.apache.jackrabbit.oak.plugins.index.search.IndexDefinition;
-import org.apache.jackrabbit.oak.plugins.index.search.spi.editor.FulltextIndexWriter;
-import org.elasticsearch.action.delete.DeleteRequest;
-import org.elasticsearch.action.delete.DeleteResponse;
-import org.elasticsearch.action.index.IndexRequest;
-import org.elasticsearch.action.index.IndexResponse;
-import org.elasticsearch.client.RequestOptions;
-import org.elasticsearch.client.RestHighLevelClient;
-import org.elasticsearch.client.indices.CreateIndexRequest;
-import org.elasticsearch.client.indices.CreateIndexResponse;
-import org.elasticsearch.common.Strings;
-import org.elasticsearch.common.settings.Settings;
-import org.elasticsearch.common.xcontent.XContentBuilder;
-import org.elasticsearch.common.xcontent.XContentFactory;
-import org.elasticsearch.common.xcontent.XContentType;
-import org.jetbrains.annotations.NotNull;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-
-import static org.apache.jackrabbit.oak.plugins.index.elasticsearch.index.ElasticsearchDocument.pathToId;
-import static org.elasticsearch.action.support.WriteRequest.RefreshPolicy.IMMEDIATE;
-import static org.elasticsearch.action.support.WriteRequest.RefreshPolicy.NONE;
-import static org.elasticsearch.common.xcontent.ToXContent.EMPTY_PARAMS;
-import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
-
-public class ElasticsearchIndexWriter implements FulltextIndexWriter<ElasticsearchDocument> {
- private static final Logger LOG = LoggerFactory.getLogger(ElasticsearchIndexWriter.class);
-
- private final ElasticsearchIndexCoordinate esIndexCoord;
- private final RestHighLevelClient client;
- private boolean shouldProvisionIndex;
-
- private final boolean isAsync;
-
- // TODO: use bulk API - https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/java-docs-bulk-processor.html
- ElasticsearchIndexWriter(@NotNull IndexDefinition indexDefinition,
- ElasticsearchIndexCoordinateFactory esIndexCoordFactory) {
- esIndexCoord = esIndexCoordFactory.getElasticsearchIndexCoordinate(indexDefinition);
- client = esIndexCoord.getClient();
-
- // TODO: ES indexing put another bit delay before docs appear in search.
- // For test without "async" indexing, we can use following hack BUT those where we
- // would setup async, we'd need to find another way.
- isAsync = indexDefinition.getDefinitionNodeState().getProperty("async") != null;
-
- shouldProvisionIndex = false;
- }
-
- @Override
- public void updateDocument(String path, ElasticsearchDocument doc) throws IOException {
- provisionIndex();
- IndexRequest request = new IndexRequest(esIndexCoord.getEsIndexName())
- .id(pathToId(path))
- // immediate refresh would slow indexing response such that next
- // search would see the effect of this indexed doc. Must only get
- // enabled in tests (hopefully there are no non-async indexes in real life)
- .setRefreshPolicy(isAsync ? NONE : IMMEDIATE)
- .source(doc.build(), XContentType.JSON);
- IndexResponse response = client.index(request, RequestOptions.DEFAULT);
- LOG.trace("update {} - {}. Response: {}", path, doc, response);
- }
-
- @Override
- public void deleteDocuments(String path) throws IOException {
- provisionIndex();
- DeleteRequest request = new DeleteRequest(esIndexCoord.getEsIndexName())
- .id(pathToId(path))
- // immediate refresh would slow indexing response such that next
- // search would see the effect of this indexed doc. Must only get
- // enabled in tests (hopefully there are no non-async indexes in real life)
- .setRefreshPolicy(isAsync ? NONE : IMMEDIATE);
- DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
- LOG.trace("delete {}. Response: {}", path, response);
-
- }
-
- @Override
- public boolean close(long timestamp) throws IOException {
- provisionIndex();
- // TODO : track index updates and return accordingly
- // TODO : if/when we do async push, this is where to wait for those ops to complete
- return false;
- }
-
- /**
- * This method <b>won't</b> immediately provision index. But, provision would be done <b>before</b>
- * any updates are sent to the index
- */
- void setProvisioningRequired() {
- shouldProvisionIndex = true;
- }
-
- private void provisionIndex() throws IOException {
- if (!shouldProvisionIndex) {
- return;
- }
-
- try {
- CreateIndexRequest request = new CreateIndexRequest(esIndexCoord.getEsIndexName());
-
- // provision settings
- request.settings(Settings.builder()
- .put("analysis.analyzer.ancestor_analyzer.type", "custom")
- .put("analysis.analyzer.ancestor_analyzer.tokenizer", "path_hierarchy"));
-
- // provision mappings
- XContentBuilder mappingBuilder = XContentFactory.jsonBuilder();
- mappingBuilder.startObject();
- {
- mappingBuilder.startObject("properties");
- {
- mappingBuilder.startObject(FieldNames.ANCESTORS)
- .field("type", "text")
- .field("analyzer", "ancestor_analyzer")
- .field("search_analyzer", "keyword")
- .field("search_quote_analyzer", "keyword")
- .endObject();
- mappingBuilder.startObject(FieldNames.PATH_DEPTH)
- .field("type", "integer")
- .endObject();
- mappingBuilder.startObject(FieldNames.SUGGEST)
- .field("type", "completion")
- .endObject();
- mappingBuilder.startObject(FieldNames.NOT_NULL_PROPS)
- .field("type", "keyword")
- .endObject();
- mappingBuilder.startObject(FieldNames.NULL_PROPS)
- .field("type", "keyword")
- .endObject();
- }
- mappingBuilder.endObject();
- }
- mappingBuilder.endObject();
- request.mapping(mappingBuilder);
-
- String requestMsg = Strings.toString(request.toXContent(jsonBuilder(), EMPTY_PARAMS));
- CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
-
- LOG.info("Updated settings {}. Response acknowledged: {}", requestMsg, response.isAcknowledged());
- } finally {
- shouldProvisionIndex = false;
- }
- }
-}
diff --git a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/index/ElasticsearchIndexWriterFactory.java b/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/index/ElasticsearchIndexWriterFactory.java
deleted file mode 100644
index c9e3ac0c97..0000000000
--- a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/index/ElasticsearchIndexWriterFactory.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.jackrabbit.oak.plugins.index.elasticsearch.index;
-
-import org.apache.jackrabbit.oak.plugins.index.elasticsearch.ElasticsearchIndexCoordinateFactory;
-import org.apache.jackrabbit.oak.plugins.index.search.IndexDefinition;
-import org.apache.jackrabbit.oak.plugins.index.search.spi.editor.FulltextIndexWriterFactory;
-import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
-import org.jetbrains.annotations.NotNull;
-
-public class ElasticsearchIndexWriterFactory implements FulltextIndexWriterFactory<ElasticsearchDocument> {
- private final ElasticsearchIndexCoordinateFactory esIndexCoordFactory;
-
- ElasticsearchIndexWriterFactory(@NotNull ElasticsearchIndexCoordinateFactory esIndexCoordFactory) {
- this.esIndexCoordFactory = esIndexCoordFactory;
- }
-
- @Override
- public ElasticsearchIndexWriter newInstance(IndexDefinition definition, NodeBuilder definitionBuilder, boolean reindex) {
- return new ElasticsearchIndexWriter(definition, esIndexCoordFactory);
- }
-}
diff --git a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/query/ElasticsearchIndex.java b/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/query/ElasticsearchIndex.java
deleted file mode 100644
index ed6c8f87f3..0000000000
--- a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/query/ElasticsearchIndex.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.jackrabbit.oak.plugins.index.elasticsearch.query;
-
-import org.apache.jackrabbit.oak.plugins.index.elasticsearch.ElasticsearchIndexCoordinateFactory;
-import org.apache.jackrabbit.oak.plugins.index.search.IndexNode;
-import org.apache.jackrabbit.oak.plugins.index.search.SizeEstimator;
-import org.apache.jackrabbit.oak.plugins.index.search.util.LMSEstimator;
-import org.apache.jackrabbit.oak.plugins.index.search.spi.query.FulltextIndex;
-import org.apache.jackrabbit.oak.plugins.index.search.spi.query.FulltextIndexPlanner;
-import org.apache.jackrabbit.oak.spi.query.Cursor;
-import org.apache.jackrabbit.oak.spi.query.Filter;
-import org.apache.jackrabbit.oak.spi.query.QueryLimits;
-import org.apache.jackrabbit.oak.spi.state.NodeState;
-import org.elasticsearch.common.Strings;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.Iterator;
-import java.util.Map;
-import java.util.WeakHashMap;
-import java.util.function.Predicate;
-
-import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.TYPE_PROPERTY_NAME;
-import static org.apache.jackrabbit.oak.plugins.index.elasticsearch.ElasticsearchIndexConstants.TYPE_ELASTICSEARCH;
-
-public class ElasticsearchIndex extends FulltextIndex {
- private static final Predicate<NodeState> ELASTICSEARCH_INDEX_DEFINITION_PREDICATE =
- state -> TYPE_ELASTICSEARCH.equals(state.getString(TYPE_PROPERTY_NAME));
- private static final Map<String, LMSEstimator> estimators = new WeakHashMap<>();
-
- // higher than some threshold below which the query should rather be answered by something else if possible
- private static final double MIN_COST = 100.1;
-
- private final ElasticsearchIndexCoordinateFactory esIndexCoordFactory;
- private final NodeState root;
-
- ElasticsearchIndex(@NotNull ElasticsearchIndexCoordinateFactory esIndexCoordFactory, @NotNull NodeState root) {
- this.esIndexCoordFactory = esIndexCoordFactory;
- this.root = root;
- }
-
- @Override
- protected String getType() {
- return TYPE_ELASTICSEARCH;
- }
-
- @Override
- protected SizeEstimator getSizeEstimator(IndexPlan plan) {
- return () -> getEstimator(plan.getPlanName()).estimate(plan.getFilter());
- }
-
- @Override
- protected Predicate<NodeState> getIndexDefinitionPredicate() {
- return ELASTICSEARCH_INDEX_DEFINITION_PREDICATE;
- }
-
- @Override
- public double getMinimumCost() {
- return MIN_COST;
- }
-
- @Override
- public String getIndexName() {
- return "elasticsearch";
- }
-
- @Override
- protected ElasticsearchIndexNode acquireIndexNode(IndexPlan plan) {
- return (ElasticsearchIndexNode) super.acquireIndexNode(plan);
- }
-
- @Override
- protected IndexNode acquireIndexNode(String indexPath) {
- ElasticsearchIndexNode elasticsearchIndexNode = ElasticsearchIndexNode.fromIndexPath(root, indexPath);
- elasticsearchIndexNode.setFactory(esIndexCoordFactory);
- return elasticsearchIndexNode;
- }
-
- @Override
- protected String getFulltextRequestString(IndexPlan plan, IndexNode indexNode) {
- return Strings.toString(ElasticsearchResultRowIterator.getESRequest(plan, getPlanResult(plan)));
- }
-
- @Override
- public Cursor query(IndexPlan plan, NodeState rootState) {
- final Filter filter = plan.getFilter();
-
- // TODO: sorting
-
- final FulltextIndexPlanner.PlanResult pr = getPlanResult(plan);
- QueryLimits settings = filter.getQueryLimits();
-
- Iterator<FulltextResultRow> itr = new ElasticsearchResultRowIterator(esIndexCoordFactory, filter, pr, plan,
- acquireIndexNode(plan), FulltextIndex::shouldInclude, getEstimator(plan.getPlanName()));
- SizeEstimator sizeEstimator = getSizeEstimator(plan);
-
- /*
- TODO: sync (nrt too??)
- if (pr.hasPropertyIndexResult() || pr.evaluateSyncNodeTypeRestriction()) {
- itr = mergePropertyIndexResult(plan, rootState, itr);
- }
- */
-
- // no concept of rewound in ES (even if it might be doing it internally, we can't do much about it
- IteratorRewoundStateProvider rewoundStateProvider = () -> 0;
- return new FulltextPathCursor(itr, rewoundStateProvider, plan, settings, sizeEstimator);
- }
-
- private LMSEstimator getEstimator(String path) {
- estimators.putIfAbsent(path, new LMSEstimator());
- return estimators.get(path);
- }
-
- @Override
- protected boolean filterReplacedIndexes() {
- return true;
- }
-}
diff --git a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/query/ElasticsearchIndexNode.java b/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/query/ElasticsearchIndexNode.java
deleted file mode 100644
index 1a90adee0c..0000000000
--- a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/query/ElasticsearchIndexNode.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.jackrabbit.oak.plugins.index.elasticsearch.query;
-
-import org.apache.jackrabbit.oak.plugins.index.elasticsearch.ElasticsearchIndexCoordinateFactory;
-import org.apache.jackrabbit.oak.plugins.index.elasticsearch.ElasticsearchIndexDefinition;
-import org.apache.jackrabbit.oak.plugins.index.search.IndexNode;
-import org.apache.jackrabbit.oak.plugins.index.search.IndexStatistics;
-import org.apache.jackrabbit.oak.spi.state.NodeState;
-import org.apache.jackrabbit.oak.spi.state.NodeStateUtils;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class ElasticsearchIndexNode implements IndexNode {
-
- private final ElasticsearchIndexDefinition indexDefinition;
- private ElasticsearchIndexCoordinateFactory factory;
-
- static ElasticsearchIndexNode fromIndexPath(@NotNull NodeState root, @NotNull String indexPath) {
- NodeState indexNS = NodeStateUtils.getNode(root, indexPath);
- ElasticsearchIndexDefinition indexDefinition = new ElasticsearchIndexDefinition(root, indexNS, indexPath);
- return new ElasticsearchIndexNode(indexDefinition);
- }
-
- private ElasticsearchIndexNode(ElasticsearchIndexDefinition indexDefinition) {
- this.indexDefinition = indexDefinition;
- }
-
- @Override
- public void release() {
- // do nothing
- }
-
- @Override
- public ElasticsearchIndexDefinition getDefinition() {
- return indexDefinition;
- }
-
- @Override
- public int getIndexNodeId() {
- // TODO: does it matter that we simply return 0 as there's no observation based _refresh_ going on here
- // and we always defer to ES to its own thing
- return 0;
- }
-
- @Override
- public @Nullable IndexStatistics getIndexStatistics() {
- return new ElasticsearchIndexStatistics(factory.getElasticsearchIndexCoordinate(indexDefinition));
- }
-
- public void setFactory(ElasticsearchIndexCoordinateFactory factory) {
- this.factory = factory;
- }
-}
diff --git a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/query/ElasticsearchIndexProvider.java b/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/query/ElasticsearchIndexProvider.java
deleted file mode 100644
index a09924291a..0000000000
--- a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/query/ElasticsearchIndexProvider.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.jackrabbit.oak.plugins.index.elasticsearch.query;
-
-import com.google.common.collect.ImmutableList;
-import org.apache.jackrabbit.oak.plugins.index.elasticsearch.ElasticsearchIndexCoordinateFactory;
-import org.apache.jackrabbit.oak.spi.query.QueryIndex;
-import org.apache.jackrabbit.oak.spi.query.QueryIndexProvider;
-import org.apache.jackrabbit.oak.spi.state.NodeState;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.List;
-
-public class ElasticsearchIndexProvider implements QueryIndexProvider {
- private final ElasticsearchIndexCoordinateFactory esIndexCoordFactory;
-
- public ElasticsearchIndexProvider(@NotNull ElasticsearchIndexCoordinateFactory esIndexCoordFactory) {
- this.esIndexCoordFactory = esIndexCoordFactory;
- }
-
- @Override
- public @NotNull List<? extends QueryIndex> getQueryIndexes(NodeState nodeState) {
- return ImmutableList.of(new ElasticsearchIndex(esIndexCoordFactory, nodeState));
- }
-}
diff --git a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/query/ElasticsearchIndexStatistics.java b/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/query/ElasticsearchIndexStatistics.java
deleted file mode 100644
index c404174660..0000000000
--- a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/query/ElasticsearchIndexStatistics.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.jackrabbit.oak.plugins.index.elasticsearch.query;
-
-import org.apache.jackrabbit.oak.plugins.index.elasticsearch.ElasticsearchIndexCoordinate;
-import org.apache.jackrabbit.oak.plugins.index.search.IndexStatistics;
-import org.elasticsearch.client.RequestOptions;
-import org.elasticsearch.client.core.CountRequest;
-import org.elasticsearch.client.core.CountResponse;
-import org.elasticsearch.index.query.QueryBuilders;
-import org.elasticsearch.search.builder.SearchSourceBuilder;
-
-import java.io.IOException;
-
-public class ElasticsearchIndexStatistics implements IndexStatistics {
- private final ElasticsearchIndexCoordinate elasticsearchIndexCoordinate;
-
- ElasticsearchIndexStatistics(ElasticsearchIndexCoordinate elasticsearchIndexCoordinate) {
- this.elasticsearchIndexCoordinate = elasticsearchIndexCoordinate;
- }
-
- @Override
- public int numDocs() {
- CountRequest countRequest = new CountRequest();
- SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
- searchSourceBuilder.query(QueryBuilders.matchAllQuery());
- countRequest.source(searchSourceBuilder);
- try {
- CountResponse count = elasticsearchIndexCoordinate.getClient().count(countRequest, RequestOptions.DEFAULT);
- return (int) count.getCount();
- } catch (IOException e) {
- // ignore failure
- return 100000;
- }
- }
-
- @Override
- public int getDocCountFor(String key) {
- CountRequest countRequest = new CountRequest();
- SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
- searchSourceBuilder.query(QueryBuilders.existsQuery(key));
- countRequest.source(searchSourceBuilder);
- try {
- CountResponse count = elasticsearchIndexCoordinate.getClient().count(countRequest, RequestOptions.DEFAULT);
- return (int) count.getCount();
- } catch (IOException e) {
- // ignore failure
- return 1000;
- }
- }
-}
diff --git a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/query/ElasticsearchResultRowIterator.java b/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/query/ElasticsearchResultRowIterator.java
deleted file mode 100644
index 27088a93a1..0000000000
--- a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/query/ElasticsearchResultRowIterator.java
+++ /dev/null
@@ -1,711 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.jackrabbit.oak.plugins.index.elasticsearch.query;
-
-import com.google.common.collect.AbstractIterator;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Queues;
-import org.apache.jackrabbit.oak.api.Type;
-import org.apache.jackrabbit.oak.commons.PathUtils;
-import org.apache.jackrabbit.oak.commons.PerfLogger;
-import org.apache.jackrabbit.oak.plugins.index.elasticsearch.ElasticsearchIndexCoordinateFactory;
-import org.apache.jackrabbit.oak.plugins.index.elasticsearch.ElasticsearchIndexDefinition;
-import org.apache.jackrabbit.oak.plugins.index.search.FieldNames;
-import org.apache.jackrabbit.oak.plugins.index.search.IndexDefinition;
-import org.apache.jackrabbit.oak.plugins.index.search.PropertyDefinition;
-import org.apache.jackrabbit.oak.plugins.index.search.util.LMSEstimator;
-import org.apache.jackrabbit.oak.plugins.index.search.spi.query.FulltextIndex;
-import org.apache.jackrabbit.oak.plugins.index.search.spi.query.FulltextIndexPlanner.PlanResult;
-import org.apache.jackrabbit.oak.spi.query.Filter;
-import org.apache.jackrabbit.oak.spi.query.QueryConstants;
-import org.apache.jackrabbit.oak.spi.query.QueryIndex.IndexPlan;
-import org.apache.jackrabbit.oak.spi.query.fulltext.*;
-import org.elasticsearch.action.search.SearchResponse;
-import org.elasticsearch.index.query.BoolQueryBuilder;
-import org.elasticsearch.index.query.QueryBuilder;
-import org.elasticsearch.index.query.QueryBuilders;
-import org.elasticsearch.search.SearchHit;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.jcr.PropertyType;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.URLDecoder;
-import java.util.ArrayList;
-import java.util.Deque;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicReference;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-import static org.apache.jackrabbit.JcrConstants.JCR_MIXINTYPES;
-import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
-import static org.apache.jackrabbit.oak.api.Type.STRING;
-import static org.apache.jackrabbit.oak.commons.PathUtils.denotesRoot;
-import static org.apache.jackrabbit.oak.commons.PathUtils.getParentPath;
-import static org.apache.jackrabbit.oak.plugins.index.elasticsearch.util.TermQueryBuilderFactory.*;
-import static org.apache.jackrabbit.oak.plugins.index.search.spi.query.FulltextIndex.isNodePath;
-import static org.apache.jackrabbit.oak.spi.query.QueryConstants.JCR_PATH;
-import static org.apache.jackrabbit.util.ISO8601.parse;
-import static org.elasticsearch.index.query.QueryBuilders.*;
-
-public class ElasticsearchResultRowIterator extends AbstractIterator<FulltextIndex.FulltextResultRow> {
- private static final Logger LOG = LoggerFactory
- .getLogger(ElasticsearchResultRowIterator.class);
- private static final PerfLogger PERF_LOGGER =
- new PerfLogger(LoggerFactory.getLogger(ElasticsearchResultRowIterator.class.getName() + ".perf"));
-
- // TODO: oak-lucene gets this via WildcardQuery class. See if ES also exposes these consts
- private static final char WILDCARD_STRING = '*';
- private static final char WILDCARD_CHAR = '?';
-
- /**
- * Batch size for fetching results from queries.
- */
- private static final int ELASTICSEARCH_QUERY_BATCH_SIZE = 1000;
-
- private static final int ELASTICSEARCH_QUERY_MAX_BATCH_SIZE = 10000;
-
-
- private final Deque<FulltextIndex.FulltextResultRow> queue = Queues.newArrayDeque();
- // TODO : find if ES can return dup docs - if so how to avoid
-// private final Set<String> seenPaths = Sets.newHashSet();
- private SearchHit lastDoc;
- private int nextBatchSize = ELASTICSEARCH_QUERY_BATCH_SIZE;
- private boolean noDocs = false;
-
- private final ElasticsearchIndexCoordinateFactory esIndexCoordFactory;
- private final Filter filter;
- private final PlanResult pr;
- private final IndexPlan plan;
- private final ElasticsearchIndexNode indexNode;
- private final RowInclusionPredicate rowInclusionPredicate;
- private final LMSEstimator estimator;
-
- ElasticsearchResultRowIterator(@NotNull ElasticsearchIndexCoordinateFactory esIndexCoordFactory,
- @NotNull Filter filter,
- @NotNull PlanResult pr,
- @NotNull IndexPlan plan,
- ElasticsearchIndexNode indexNode,
- RowInclusionPredicate rowInclusionPredicate,
- LMSEstimator estimator) {
- this.esIndexCoordFactory = esIndexCoordFactory;
- this.filter = filter;
- this.pr = pr;
- this.plan = plan;
- this.indexNode = indexNode;
- this.rowInclusionPredicate = rowInclusionPredicate != null ? rowInclusionPredicate : RowInclusionPredicate.NOOP;
- this.estimator = estimator;
- }
-
- @Override
- protected FulltextIndex.FulltextResultRow computeNext() {
- if (!queue.isEmpty() || loadDocs()) {
- return queue.remove();
- } else {
- return endOfData();
- }
- }
-
- /**
- * Loads the lucene documents in batches
- * @return true if any document is loaded
- */
- private boolean loadDocs() {
-
- if (noDocs) {
- return false;
- }
-
- SearchHit lastDocToRecord = null;
-
- checkState(indexNode != null);
- try {
- ElasticsearchSearcher searcher = getCurrentSearcher(indexNode);
- QueryBuilder query = getESRequest(plan, pr);
- // TODO: custom scoring
-
- SearchResponse docs;
- long start = PERF_LOGGER.start();
- while (true) {
- LOG.debug("loading {} entries for query {}", nextBatchSize, query);
- docs = searcher.search(query, nextBatchSize);
-
- SearchHit[] searchHits = docs.getHits().getHits();
- PERF_LOGGER.end(start, -1, "{} ...", searchHits.length);
-
- estimator.update(filter, docs.getHits().getTotalHits().value);
-
- if (searchHits.length < nextBatchSize) {
- noDocs = true;
- }
-
- nextBatchSize = (int) Math.min(nextBatchSize * 2L, ELASTICSEARCH_QUERY_MAX_BATCH_SIZE);
-
- // TODO: faceting
-
- // TODO: excerpt
-
- // TODO: explanation
-
- // TODO: sim search
-
- for (SearchHit doc : searchHits) {
- // TODO : excerpts
-
- FulltextIndex.FulltextResultRow row = convertToRow(doc);
- if (row != null) {
- queue.add(row);
- }
- lastDocToRecord = doc;
- }
-
- if (queue.isEmpty() && searchHits.length > 0) {
- //queue is still empty but more results can be fetched
- //from Lucene so still continue
- lastDoc = lastDocToRecord;
- } else {
- break;
- }
- }
-
- // TODO: spellcheck else if (luceneRequestFacade.getLuceneRequest() instanceof SpellcheckHelper.SpellcheckQuery) {
- // TODO: suggest } else if (luceneRequestFacade.getLuceneRequest() instanceof SuggestHelper.SuggestQuery) {
- } catch (Exception e) {
- LOG.warn("query via {} failed.", this, e);
- } finally {
- indexNode.release();
- }
-
- if (lastDocToRecord != null) {
- this.lastDoc = lastDocToRecord;
- }
-
- return !queue.isEmpty();
- }
-
- private ElasticsearchSearcher getCurrentSearcher(ElasticsearchIndexNode indexNode) {
- return new ElasticsearchSearcher(esIndexCoordFactory, indexNode);
- }
-
- private FulltextIndex.FulltextResultRow convertToRow(SearchHit hit) throws IOException {
- String id = hit.getId();
- String path = idToPath(id);
- if (path != null) {
- if ("".equals(path)) {
- path = "/";
- }
- if (pr.isPathTransformed()) {
- String originalPath = path;
- path = pr.transformPath(path);
-
- if (path == null) {
- LOG.trace("Ignoring path {} : Transformation returned null", originalPath);
- return null;
- }
- }
-
- boolean shouldIncludeForHierarchy = rowInclusionPredicate.shouldInclude(path, plan);
- LOG.trace("Matched path {}; shouldIncludeForHierarchy: {}", path, shouldIncludeForHierarchy);
- return shouldIncludeForHierarchy ? new FulltextIndex.FulltextResultRow(path, hit.getScore(), null,
- null, null)
- : null;
- }
- return null;
- }
-
- public interface RowInclusionPredicate {
- boolean shouldInclude(@NotNull String path, @NotNull IndexPlan plan);
-
- RowInclusionPredicate NOOP = (@NotNull String path, @NotNull IndexPlan plan) -> true;
- }
-
- /**
- * Get the Elasticsearch query for the given filter.
- *
- * @param plan index plan containing filter details
- * @param planResult
- * @return the Lucene query
- */
- static QueryBuilder getESRequest(IndexPlan plan, PlanResult planResult) {
- List<QueryBuilder> qs = new ArrayList<>();
- Filter filter = plan.getFilter();
- FullTextExpression ft = filter.getFullTextConstraint();
- ElasticsearchIndexDefinition defn = (ElasticsearchIndexDefinition) planResult.indexDefinition;
-
- if (ft != null) {
- qs.add(getFullTextQuery(ft, planResult));
- } else {
- // there might be no full-text constraint
- // when using the LowCostLuceneIndexProvider
- // which is used for testing
- }
-
-
- //Check if native function is supported
- Filter.PropertyRestriction pr = null;
- if (defn.hasFunctionDefined()) {
- pr = filter.getPropertyRestriction(defn.getFunctionName());
- }
-
- if (pr != null) {
- String query = String.valueOf(pr.first.getValue(pr.first.getType()));
- // TODO: more like this
-
- // TODO: spellcheck
-
- // TODO: suggest
-
- qs.add(QueryBuilders.queryStringQuery(query));
- } else if (planResult.evaluateNonFullTextConstraints()) {
- addNonFullTextConstraints(qs, plan, planResult);
- }
-
- // TODO: sort with no other restriction
-
- if (qs.size() == 0) {
-
- // TODO: what happens here in planning mode (specially, apparently for things like rep:similar)
-
- //For purely nodeType based queries all the documents would have to
- //be returned (if the index definition has a single rule)
- if (planResult.evaluateNodeTypeRestriction()) {
- return matchAllQuery();
- }
-
- throw new IllegalStateException("No query created for filter " + filter);
- }
- return performAdditionalWraps(qs);
- }
-
- private static QueryBuilder getFullTextQuery(FullTextExpression ft, final PlanResult pr) {
- // a reference to the query, so it can be set in the visitor
- // (a "non-local return")
- final AtomicReference<QueryBuilder> result = new AtomicReference<>();
- ft.accept(new FullTextVisitor() {
-
- @Override
- public boolean visit(FullTextContains contains) {
- visitTerm(contains.getPropertyName(), contains.getRawText(), null, contains.isNot());
- return true;
- }
-
- @Override
- public boolean visit(FullTextOr or) {
- BoolQueryBuilder q = boolQuery();
- for (FullTextExpression e : or.list) {
- QueryBuilder x = getFullTextQuery(e, pr);
- q.should(x);
- }
- result.set(q);
- return true;
- }
-
- @Override
- public boolean visit(FullTextAnd and) {
- BoolQueryBuilder q = boolQuery();
- for (FullTextExpression e : and.list) {
- QueryBuilder x = getFullTextQuery(e, pr);
- // TODO: see OAK-2434 and see if ES also can't work without unwrapping
- /* Only unwrap the clause if MUST_NOT(x) */
- boolean hasMustNot = false;
- if (x instanceof BoolQueryBuilder) {
- BoolQueryBuilder bq = (BoolQueryBuilder) x;
- if (bq.mustNot().size() == 1
- // no other clauses
- && bq.should().isEmpty() && bq.must().isEmpty() && bq.filter().isEmpty()) {
- hasMustNot = true;
- q.mustNot(bq.mustNot().get(0));
- }
- }
-
- if (!hasMustNot) {
- q.must(x);
- }
- }
- result.set(q);
- return true;
- }
-
- @Override
- public boolean visit(FullTextTerm term) {
- return visitTerm(term.getPropertyName(), term.getText(), term.getBoost(), term.isNot());
- }
-
- private boolean visitTerm(String propertyName, String text, String boost, boolean not) {
- String p = getLuceneFieldName(propertyName, pr);
- QueryBuilder q = tokenToQuery(text, p, pr);
- if (q == null) {
- return false;
- }
- if (boost != null) {
- q.boost(Float.parseFloat(boost));
- }
- if (not) {
- BoolQueryBuilder bq = boolQuery();
- bq.mustNot(q);
- result.set(bq);
- } else {
- result.set(q);
- }
- return true;
- }
- });
- return result.get();
- }
-
- private static QueryBuilder tokenToQuery(String text, String fieldName, PlanResult pr) {
- QueryBuilder ret;
- IndexDefinition.IndexingRule indexingRule = pr.indexingRule;
- //Expand the query on fulltext field
- if (FieldNames.FULLTEXT.equals(fieldName) &&
- !indexingRule.getNodeScopeAnalyzedProps().isEmpty()) {
- BoolQueryBuilder in = boolQuery();
- for (PropertyDefinition pd : indexingRule.getNodeScopeAnalyzedProps()) {
- QueryBuilder q = matchQuery(FieldNames.createAnalyzedFieldName(pd.name), text);
- q.boost(pd.boost);
- in.should(q);
- }
-
- //Add the query for actual fulltext field also. That query would
- //not be boosted
- in.should(matchQuery(fieldName, text));
- ret = in;
- } else {
- ret = matchQuery(fieldName, text);
- }
-
- return ret;
- }
-
- private static String getLuceneFieldName(@Nullable String p, PlanResult pr) {
- if (p == null) {
- return FieldNames.FULLTEXT;
- }
-
- if (isNodePath(p)) {
- if (pr.isPathTransformed()) {
- p = PathUtils.getName(p);
- } else {
- //Get rid of /* as aggregated fulltext field name is the
- //node relative path
- p = FieldNames.createFulltextFieldName(PathUtils.getParentPath(p));
- }
- } else {
- if (pr.isPathTransformed()) {
- p = PathUtils.getName(p);
- }
- p = FieldNames.createAnalyzedFieldName(p);
- }
-
- if ("*".equals(p)) {
- p = FieldNames.FULLTEXT;
- }
- return p;
- }
-
- /**
- * Perform additional wraps on the list of queries to allow, for example, the NOT CONTAINS to
- * play properly when sent to lucene.
- *
- * @param qs the list of queries. Cannot be null.
- * @return the request facade
- */
- @NotNull
- private static QueryBuilder performAdditionalWraps(@NotNull List<QueryBuilder> qs) {
- checkNotNull(qs);
- if (qs.size() == 1) {
- // we don't need to worry about all-negatives in a bool query as
- // BoolQueryBuilder.adjustPureNegative is on by default anyway
- return qs.get(0);
- }
- BoolQueryBuilder bq = new BoolQueryBuilder();
- // TODO: while I've attempted to translate oak-lucene code to corresponding ES one but I am
- // unable to make sense of this code
- for (QueryBuilder q : qs) {
- boolean unwrapped = false;
- if (q instanceof BoolQueryBuilder) {
- unwrapped = unwrapMustNot((BoolQueryBuilder) q, bq);
- }
-
- if (!unwrapped) {
- bq.must(q);
- }
- }
- return bq;
- }
-
- /**
- * unwraps any NOT clauses from the provided boolean query into another boolean query.
- *
- * @param input the query to be analysed for the existence of NOT clauses. Cannot be null.
- * @param output the query where the unwrapped NOTs will be saved into. Cannot be null.
- * @return true if there where at least one unwrapped NOT. false otherwise.
- */
- private static boolean unwrapMustNot(@NotNull BoolQueryBuilder input, @NotNull BoolQueryBuilder output) {
- checkNotNull(input);
- checkNotNull(output);
- boolean unwrapped = false;
- for (QueryBuilder mustNot : input.mustNot()) {
- output.mustNot(mustNot);
- unwrapped = true;
- }
- if (unwrapped) {
- // if we have unwrapped "must not" conditions,
- // then we need to unwrap "must" conditions as well
- for (QueryBuilder must : input.must()) {
- output.must(must);
- }
- }
-
- return unwrapped;
- }
-
- private static void addNonFullTextConstraints(List<QueryBuilder> qs,
- IndexPlan plan, PlanResult planResult) {
- Filter filter = plan.getFilter();
- IndexDefinition defn = planResult.indexDefinition;
- if (!filter.matchesAllTypes()) {
- addNodeTypeConstraints(planResult.indexingRule, qs, filter);
- }
-
- String path = FulltextIndex.getPathRestriction(plan);
- switch (filter.getPathRestriction()) {
- case ALL_CHILDREN:
- if (defn.evaluatePathRestrictions()) {
- if ("/".equals(path)) {
- break;
- }
- qs.add(newAncestorQuery(path));
- }
- break;
- case DIRECT_CHILDREN:
- if (defn.evaluatePathRestrictions()) {
- BoolQueryBuilder bq = boolQuery();
- bq.must(newAncestorQuery(path));
- bq.must(newDepthQuery(path, planResult));
- qs.add(bq);
- }
- break;
- case EXACT:
- // For transformed paths, we can only add path restriction if absolute path to property can be
- // deduced
- if (planResult.isPathTransformed()) {
- String parentPathSegment = planResult.getParentPathSegment();
- if ( ! Iterables.any(PathUtils.elements(parentPathSegment), "*"::equals)) {
- qs.add(newPathQuery(path + parentPathSegment));
- }
- } else {
- qs.add(newPathQuery(path));
- }
- break;
- case PARENT:
- if (denotesRoot(path)) {
- // there's no parent of the root node
- // we add a path that can not possibly occur because there
- // is no way to say "match no documents" in Lucene
- qs.add(newPathQuery("///"));
- } else {
- // For transformed paths, we can only add path restriction if absolute path to property can be
- // deduced
- if (planResult.isPathTransformed()) {
- String parentPathSegment = planResult.getParentPathSegment();
- if ( ! Iterables.any(PathUtils.elements(parentPathSegment), "*"::equals)) {
- qs.add(newPathQuery(getParentPath(path) + parentPathSegment));
- }
- } else {
- qs.add(newPathQuery(getParentPath(path)));
- }
- }
- break;
- case NO_RESTRICTION:
- break;
- }
-
- for (Filter.PropertyRestriction pr : filter.getPropertyRestrictions()) {
- String name = pr.propertyName;
-
- if (QueryConstants.REP_EXCERPT.equals(name) || QueryConstants.OAK_SCORE_EXPLANATION.equals(name)
- || QueryConstants.REP_FACET.equals(name)) {
- continue;
- }
-
- if (QueryConstants.RESTRICTION_LOCAL_NAME.equals(name)) {
- if (planResult.evaluateNodeNameRestriction()) {
- QueryBuilder q = createNodeNameQuery(pr);
- if (q != null) {
- qs.add(q);
- }
- }
- continue;
- }
-
- if (pr.first != null && pr.first.equals(pr.last) && pr.firstIncluding
- && pr.lastIncluding) {
- String first = pr.first.getValue(STRING);
- first = first.replace("\\", "");
- if (JCR_PATH.equals(name)) {
- qs.add(newPathQuery(first));
- continue;
- } else if ("*".equals(name)) {
- //TODO Revisit reference constraint. For performant impl
- //references need to be indexed in a different manner
- addReferenceConstraint(first, qs);
- continue;
- }
- }
-
- PropertyDefinition pd = planResult.getPropDefn(pr);
- if (pd == null) {
- continue;
- }
-
- QueryBuilder q = createQuery(planResult.getPropertyName(pr), pr, pd);
- if (q != null) {
- qs.add(q);
- }
- }
- }
-
- private static void addNodeTypeConstraints(IndexDefinition.IndexingRule defn, List<QueryBuilder> qs, Filter filter) {
- BoolQueryBuilder bq = boolQuery();
- PropertyDefinition primaryType = defn.getConfig(JCR_PRIMARYTYPE);
- //TODO OAK-2198 Add proper nodeType query support
-
- if (primaryType != null && primaryType.propertyIndex) {
- for (String type : filter.getPrimaryTypes()) {
- bq.should(newNodeTypeQuery(type));
- }
- }
-
- PropertyDefinition mixinType = defn.getConfig(JCR_MIXINTYPES);
- if (mixinType != null && mixinType.propertyIndex) {
- for (String type : filter.getMixinTypes()) {
- bq.should(newMixinTypeQuery(type));
- }
- }
-
- if (bq.hasClauses()) {
- qs.add(bq);
- }
- }
-
- private static QueryBuilder createNodeNameQuery(Filter.PropertyRestriction pr) {
- String first = pr.first != null ? pr.first.getValue(STRING) : null;
- if (pr.first != null && pr.first.equals(pr.last) && pr.firstIncluding
- && pr.lastIncluding) {
- // [property]=[value]
- return termQuery(FieldNames.NODE_NAME, first);
- }
-
- if (pr.isLike) {
- return createLikeQuery(FieldNames.NODE_NAME, first);
- }
-
- throw new IllegalStateException("For nodeName queries only EQUALS and LIKE are supported " + pr);
- }
-
- private static QueryBuilder createLikeQuery(String name, String first) {
- first = first.replace('%', WILDCARD_STRING);
- first = first.replace('_', WILDCARD_CHAR);
-
- QueryBuilders.wildcardQuery(name, first);
-
- int indexOfWS = first.indexOf(WILDCARD_STRING);
- int indexOfWC = first.indexOf(WILDCARD_CHAR);
- int len = first.length();
-
- if (indexOfWS == len || indexOfWC == len) {
- // remove trailing "*" for prefixquery
- first = first.substring(0, first.length() - 1);
- if (JCR_PATH.equals(name)) {
- return newPrefixPathQuery(first);
- } else {
- return newPrefixQuery(name, first);
- }
- } else {
- if (JCR_PATH.equals(name)) {
- return newWildcardPathQuery(first);
- } else {
- return newWildcardQuery(name, first);
- }
- }
- }
-
- private static void addReferenceConstraint(String uuid, List<QueryBuilder> qs) {
- // TODO: this seems very bad as a query - do we really want to support it. In fact, is it even used?
- // reference query
- qs.add(QueryBuilders.multiMatchQuery(uuid));
- }
-
- @Nullable
- private static QueryBuilder createQuery(String propertyName, Filter.PropertyRestriction pr,
- PropertyDefinition defn) {
- int propType = FulltextIndex.determinePropertyType(defn, pr);
-
- if (pr.isNullRestriction()) {
- return newNullPropQuery(defn.name);
- }
-
- //If notNullCheckEnabled explicitly enabled use the simple TermQuery
- //otherwise later fallback to range query
- if (pr.isNotNullRestriction() && defn.notNullCheckEnabled) {
- return newNotNullPropQuery(defn.name);
- }
-
- QueryBuilder in;
- switch (propType) {
- case PropertyType.DATE: {
- in = newPropertyRestrictionQuery(propertyName, false, pr,
- value -> parse(value.getValue(Type.DATE)).getTime());
- break;
- }
- case PropertyType.DOUBLE: {
- in = newPropertyRestrictionQuery(propertyName, false, pr,
- value -> value.getValue(Type.DOUBLE));
- break;
- }
- case PropertyType.LONG: {
- in = newPropertyRestrictionQuery(propertyName, false, pr,
- value -> value.getValue(Type.LONG));
- break;
- }
- default: {
- if (pr.isLike) {
- return createLikeQuery(propertyName, pr.first.getValue(STRING));
- }
-
- //TODO Confirm that all other types can be treated as string
- in = newPropertyRestrictionQuery(propertyName, true, pr,
- value -> value.getValue(Type.STRING));
- }
- }
-
- if (in != null) {
- return in;
- }
-
- throw new IllegalStateException("PropertyRestriction not handled " + pr + " for index " + defn);
- }
-
- private static String idToPath(String id) throws UnsupportedEncodingException {
- return URLDecoder.decode(id, "UTF-8");
- }
-}
diff --git a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/query/ElasticsearchSearcher.java b/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/query/ElasticsearchSearcher.java
deleted file mode 100644
index 24a7cf6cb3..0000000000
--- a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/query/ElasticsearchSearcher.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.jackrabbit.oak.plugins.index.elasticsearch.query;
-
-import org.apache.jackrabbit.oak.plugins.index.elasticsearch.ElasticsearchIndexCoordinateFactory;
-import org.apache.jackrabbit.oak.plugins.index.elasticsearch.ElasticsearchIndexCoordinate;
-import org.apache.jackrabbit.oak.plugins.index.elasticsearch.ElasticsearchIndexDefinition;
-import org.apache.jackrabbit.oak.plugins.index.search.FieldNames;
-import org.elasticsearch.action.search.SearchRequest;
-import org.elasticsearch.action.search.SearchResponse;
-import org.elasticsearch.client.RequestOptions;
-import org.elasticsearch.client.RestHighLevelClient;
-import org.elasticsearch.index.query.QueryBuilder;
-import org.elasticsearch.search.builder.SearchSourceBuilder;
-import org.jetbrains.annotations.NotNull;
-
-import java.io.IOException;
-
-public class ElasticsearchSearcher {
- private final ElasticsearchIndexCoordinate esIndexCoord;
- private final RestHighLevelClient client;
-
- ElasticsearchSearcher(@NotNull ElasticsearchIndexCoordinateFactory esIndexCoordFactory,
- @NotNull ElasticsearchIndexNode indexNode) {
- ElasticsearchIndexDefinition defn = indexNode.getDefinition();
- esIndexCoord = esIndexCoordFactory.getElasticsearchIndexCoordinate(defn);
- client = esIndexCoord.getClient();
- }
-
- public SearchResponse search(QueryBuilder query, int batchSize) throws IOException {
- SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder()
- .query(query)
- .fetchSource(false)
- .storedField(FieldNames.PATH)
- .size(batchSize)
- ;
-
- SearchRequest request = new SearchRequest(esIndexCoord.getEsIndexName())
- .source(searchSourceBuilder);
-
- return client.search(request, RequestOptions.DEFAULT);
- }
-}
diff --git a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/util/ElasticsearchIndexDefinitionBuilder.java b/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/util/ElasticsearchIndexDefinitionBuilder.java
deleted file mode 100644
index d41b766fb3..0000000000
--- a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/util/ElasticsearchIndexDefinitionBuilder.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.jackrabbit.oak.plugins.index.elasticsearch.util;
-
-import org.apache.jackrabbit.oak.plugins.index.search.util.IndexDefinitionBuilder;
-
-import static org.apache.jackrabbit.oak.plugins.index.elasticsearch.ElasticsearchIndexConstants.TYPE_ELASTICSEARCH;
-
-public class ElasticsearchIndexDefinitionBuilder extends IndexDefinitionBuilder {
- @Override
- protected String getIndexType() {
- return TYPE_ELASTICSEARCH;
- }
-}
diff --git a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/util/TermQueryBuilderFactory.java b/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/util/TermQueryBuilderFactory.java
deleted file mode 100644
index ec4d43a276..0000000000
--- a/oak-search-elastic/src/main/java/org/apache/jackrabbit/oak/plugins/index/elasticsearch/util/TermQueryBuilderFactory.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.jackrabbit.oak.plugins.index.elasticsearch.util;
-
-import org.apache.jackrabbit.oak.api.PropertyValue;
-import org.apache.jackrabbit.oak.api.Type;
-import org.apache.jackrabbit.oak.commons.PathUtils;
-import org.apache.jackrabbit.oak.plugins.index.search.FieldNames;
-import org.apache.jackrabbit.oak.plugins.index.search.PropertyDefinition;
-import org.apache.jackrabbit.oak.plugins.index.search.spi.query.FulltextIndexPlanner;
-import org.apache.jackrabbit.oak.spi.query.Filter;
-import org.elasticsearch.index.query.*;
-import org.jetbrains.annotations.NotNull;
-
-import javax.jcr.PropertyType;
-import java.util.List;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-
-import static org.apache.jackrabbit.JcrConstants.JCR_MIXINTYPES;
-import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
-import static org.apache.jackrabbit.oak.plugins.index.search.FieldNames.PATH;
-import static org.apache.jackrabbit.oak.plugins.index.search.FieldNames.PATH_DEPTH;
-import static org.elasticsearch.index.query.QueryBuilders.*;
-
-@SuppressWarnings("SpellCheckingInspection")
-public class TermQueryBuilderFactory {
- /**
- * Private constructor.
- */
- private TermQueryBuilderFactory() {
- }
-
- private static ExistsQueryBuilder newExistsQuery(String field) {
- return QueryBuilders.existsQuery(field);
- }
-
- private static TermQueryBuilder newFulltextQuery(String ft) {
- return termQuery(FieldNames.FULLTEXT, ft);
- }
-
- private static TermQueryBuilder newFulltextQuery(String ft, String field) {
- if (field == null || "*".equals(field)) {
- return newFulltextQuery(ft);
- }
- return termQuery(field, ft);
- }
-
- public static PrefixQueryBuilder newPrefixQuery(String field, @NotNull String value) {
- return prefixQuery(keywordFieldName(field), value);
- }
-
- public static WildcardQueryBuilder newWildcardQuery(String field, @NotNull String value) {
- return wildcardQuery(keywordFieldName(field), value);
- }
-
- public static TermQueryBuilder newPathQuery(String path) {
- return termQuery(PATH, preparePath(path));
- }
-
- public static PrefixQueryBuilder newPrefixPathQuery(String path) {
- return prefixQuery(PATH, preparePath(path));
- }
-
- public static WildcardQueryBuilder newWildcardPathQuery(@NotNull String value) {
- return wildcardQuery(PATH, value);
- }
-
- public static TermQueryBuilder newAncestorQuery(String path){
- return termQuery(FieldNames.ANCESTORS, preparePath(path));
- }
-
- public static TermQueryBuilder newDepthQuery(String path, FulltextIndexPlanner.PlanResult planResult) {
- int depth = PathUtils.getDepth(path) + planResult.getParentDepth() + 1;
- return QueryBuilders.termQuery(PATH_DEPTH, depth);
- }
-
- public static TermQueryBuilder newNodeTypeQuery(String type) {
- return termQuery(keywordFieldName(JCR_PRIMARYTYPE), type);
- }
-
- public static TermQueryBuilder newMixinTypeQuery(String type) {
- return termQuery(keywordFieldName(JCR_MIXINTYPES), type);
- }
-
- public static TermQueryBuilder newNotNullPropQuery(String propName) {
- return termQuery(FieldNames.NOT_NULL_PROPS, propName);
- }
-
- public static TermQueryBuilder newNullPropQuery(String propName) {
- return termQuery(FieldNames.NULL_PROPS, propName);
- }
-
- private static <R> RangeQueryBuilder newRangeQuery(String field,
- R first, R last, boolean firstIncluding, boolean lastIncluding) {
- return QueryBuilders.rangeQuery(field)
- .from(first).to(last)
- .includeLower(firstIncluding).includeUpper(lastIncluding);
- }
-
- private static <R> BoolQueryBuilder newInQuery(String field, List<R> values) {
- BoolQueryBuilder bq = boolQuery();
- for (R value : values) {
- bq.should(newRangeQuery(field, value, value, true, true));
- }
- return bq;
- }
-
- public static <R> QueryBuilder newPropertyRestrictionQuery(String propertyName, boolean isString,
- Filter.PropertyRestriction pr,
- Function<PropertyValue, R> propToObj) {
- if (isString) {
- propertyName = keywordFieldName(propertyName);
- }
-
- R first = pr.first != null ? propToObj.apply(pr.first) : null;
- R last = pr.last != null ? propToObj.apply(pr.last) : null;
- if (pr.first != null && pr.first.equals(pr.last) && pr.firstIncluding
- && pr.lastIncluding) {
- // [property]=[value]
- return termQuery(propertyName, first);
- } else if (pr.first != null && pr.last != null) {
- return newRangeQuery(propertyName, first, last,
- pr.firstIncluding, pr.lastIncluding);
- } else if (pr.first != null && pr.last == null) {
- // '>' & '>=' use cases
- return newRangeQuery(propertyName, first, null, pr.firstIncluding, true);
- } else if (pr.last != null && !pr.last.equals(pr.first)) {
- // '<' & '<='
- return newRangeQuery(propertyName, null, last, true, pr.lastIncluding);
- } else if (pr.list != null) {
- return newInQuery(propertyName, pr.list.stream()
- .map(propToObj::apply)
- .collect(Collectors.toList()));
- } else if (pr.isNotNullRestriction()) {
- // not null. For date lower bound of zero can be used
- return newExistsQuery(propertyName);
- } else {
- return null;
- }
- }
-
- private static String preparePath(String path) {
- if (!"/".equals(path) && !path.startsWith("/")) {
- path = "/" + path;
- }
- return path;
- }
-
- // As per https://www.elastic.co/blog/strings-are-dead-long-live-strings
- private static String keywordFieldName(String propName) {
- return propName + "." + "keyword";
- }
-}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index bad8dd5e83..ec4a49b562 100644
--- a/pom.xml
+++ b/pom.xml
@@ -74,7 +74,6 @@
<module>oak-segment-tar</module>
<module>oak-segment-azure</module>
<module>oak-benchmarks</module>
- <module>oak-search-elastic</module>
</modules>
<build>