You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2021/12/21 09:59:09 UTC
[syncope] branch master updated: Upgrading Elasticsearch (#298)
This is an automated email from the ASF dual-hosted git repository.
ilgrosso pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git
The following commit(s) were added to refs/heads/master by this push:
new 4880e0d Upgrading Elasticsearch (#298)
4880e0d is described below
commit 4880e0dd52ab243c1a56e41bb2d7a6ff2dd6e37d
Author: Francesco Chicchiriccò <il...@users.noreply.github.com>
AuthorDate: Tue Dec 21 10:57:18 2021 +0100
Upgrading Elasticsearch (#298)
---
ext/elasticsearch/client-elasticsearch/pom.xml | 18 +-
.../client/ElasticsearchClientContext.java | 5 +-
.../client/ElasticsearchClientFactoryBean.java | 32 +-
.../client/ElasticsearchIndexManager.java | 177 +++++-----
.../elasticsearch/client/ElasticsearchUtils.java | 118 +++----
ext/elasticsearch/persistence-jpa/pom.xml | 5 +
.../jpa/ElasticsearchPersistenceContext.java | 4 +-
.../jpa/dao/ElasticsearchAnySearchDAO.java | 377 ++++++++++++---------
.../jpa/dao/ElasticsearchAnySearchDAOTest.java | 58 ++--
ext/elasticsearch/provisioning-java/pom.xml | 2 +-
.../java/job/ElasticsearchReindex.java | 52 +--
.../syncope/fit/core/NotificationTaskITCase.java | 6 +-
pom.xml | 30 +-
13 files changed, 459 insertions(+), 425 deletions(-)
diff --git a/ext/elasticsearch/client-elasticsearch/pom.xml b/ext/elasticsearch/client-elasticsearch/pom.xml
index d7bd416..10bf6c8 100644
--- a/ext/elasticsearch/client-elasticsearch/pom.xml
+++ b/ext/elasticsearch/client-elasticsearch/pom.xml
@@ -45,25 +45,21 @@ under the License.
</dependency>
<dependency>
- <groupId>org.elasticsearch.client</groupId>
- <artifactId>elasticsearch-rest-high-level-client</artifactId>
+ <groupId>co.elastic.clients</groupId>
+ <artifactId>elasticsearch-java</artifactId>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
</dependency>
<dependency>
- <groupId>org.elasticsearch</groupId>
- <artifactId>elasticsearch</artifactId>
- </dependency>
-
- <dependency>
- <groupId>com.fasterxml.jackson.dataformat</groupId>
- <artifactId>jackson-dataformat-smile</artifactId>
+ <groupId>jakarta.json</groupId>
+ <artifactId>jakarta.json-api</artifactId>
</dependency>
+
<dependency>
- <groupId>com.fasterxml.jackson.dataformat</groupId>
- <artifactId>jackson-dataformat-cbor</artifactId>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
</dependency>
</dependencies>
diff --git a/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchClientContext.java b/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchClientContext.java
index 7e37d50..dbacb5e 100644
--- a/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchClientContext.java
+++ b/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchClientContext.java
@@ -18,13 +18,12 @@
*/
package org.apache.syncope.ext.elasticsearch.client;
+import co.elastic.clients.elasticsearch.ElasticsearchClient;
import java.util.List;
-
import org.apache.http.HttpHost;
import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
import org.apache.syncope.core.persistence.api.dao.GroupDAO;
import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
@@ -61,7 +60,7 @@ public class ElasticsearchClientContext {
@Bean
@Autowired
public ElasticsearchIndexManager elasticsearchIndexManager(
- final RestHighLevelClient client,
+ final ElasticsearchClient client,
final ElasticsearchUtils elasticsearchUtils) {
return new ElasticsearchIndexManager(client, elasticsearchUtils);
diff --git a/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchClientFactoryBean.java b/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchClientFactoryBean.java
index 39246a9..1a6aae4 100644
--- a/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchClientFactoryBean.java
+++ b/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchClientFactoryBean.java
@@ -18,6 +18,9 @@
*/
package org.apache.syncope.ext.elasticsearch.client;
+import co.elastic.clients.elasticsearch.ElasticsearchClient;
+import co.elastic.clients.json.jackson.JacksonJsonpMapper;
+import co.elastic.clients.transport.rest_client.RestClientTransport;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.List;
@@ -31,14 +34,13 @@ import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.message.BasicHeader;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
-import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
/**
- * Spring {@link FactoryBean} for getting the Elasticsearch's {@link RestHighLevelClient} singleton instance.
+ * Spring {@link FactoryBean} for getting the {@link ElasticsearchClient} singleton instance.
*/
-public class ElasticsearchClientFactoryBean implements FactoryBean<RestHighLevelClient>, DisposableBean {
+public class ElasticsearchClientFactoryBean implements FactoryBean<ElasticsearchClient>, DisposableBean {
private final List<HttpHost> hosts;
@@ -52,7 +54,9 @@ public class ElasticsearchClientFactoryBean implements FactoryBean<RestHighLevel
private String apiKeySecret;
- private RestHighLevelClient client;
+ private RestClient restClient;
+
+ private ElasticsearchClient client;
public ElasticsearchClientFactoryBean(final List<HttpHost> hosts) {
this.hosts = hosts;
@@ -91,25 +95,27 @@ public class ElasticsearchClientFactoryBean implements FactoryBean<RestHighLevel
}
@Override
- public RestHighLevelClient getObject() throws Exception {
+ public ElasticsearchClient getObject() throws Exception {
synchronized (this) {
if (client == null) {
- RestClientBuilder restClient = RestClient.builder(hosts.toArray(new HttpHost[0]));
+ RestClientBuilder builder = RestClient.builder(hosts.toArray(HttpHost[]::new));
if (username != null && password != null) {
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(
AuthScope.ANY, new UsernamePasswordCredentials(username, password));
- restClient.setHttpClientConfigCallback(b -> b.setDefaultCredentialsProvider(credentialsProvider));
+ builder.setHttpClientConfigCallback(b -> b.setDefaultCredentialsProvider(credentialsProvider));
} else if (serviceToken != null) {
- restClient.setDefaultHeaders(
+ builder.setDefaultHeaders(
new Header[] { new BasicHeader(HttpHeaders.AUTHORIZATION, "Bearer " + serviceToken) });
} else if (apiKeyId != null && apiKeySecret != null) {
String apiKeyAuth = Base64.getEncoder().encodeToString(
(apiKeyId + ":" + apiKeySecret).getBytes(StandardCharsets.UTF_8));
- restClient.setDefaultHeaders(
+ builder.setDefaultHeaders(
new Header[] { new BasicHeader(HttpHeaders.AUTHORIZATION, "ApiKey " + apiKeyAuth) });
}
- client = new RestHighLevelClient(restClient);
+
+ restClient = builder.build();
+ client = new ElasticsearchClient(new RestClientTransport(restClient, new JacksonJsonpMapper()));
}
}
return client;
@@ -117,13 +123,13 @@ public class ElasticsearchClientFactoryBean implements FactoryBean<RestHighLevel
@Override
public Class<?> getObjectType() {
- return RestHighLevelClient.class;
+ return ElasticsearchClient.class;
}
@Override
public void destroy() throws Exception {
- if (client != null) {
- client.close();
+ if (restClient != null) {
+ restClient.close();
}
}
}
diff --git a/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchIndexManager.java b/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchIndexManager.java
index b313dca..6aaef95 100644
--- a/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchIndexManager.java
+++ b/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchIndexManager.java
@@ -18,30 +18,32 @@
*/
package org.apache.syncope.ext.elasticsearch.client;
+import co.elastic.clients.elasticsearch.ElasticsearchClient;
+import co.elastic.clients.elasticsearch._types.ElasticsearchException;
+import co.elastic.clients.elasticsearch._types.analysis.CustomNormalizer;
+import co.elastic.clients.elasticsearch._types.analysis.Normalizer;
+import co.elastic.clients.elasticsearch._types.mapping.DynamicTemplate;
+import co.elastic.clients.elasticsearch._types.mapping.KeywordProperty;
+import co.elastic.clients.elasticsearch._types.mapping.Property;
+import co.elastic.clients.elasticsearch._types.mapping.TypeMapping;
+import co.elastic.clients.elasticsearch.core.DeleteRequest;
+import co.elastic.clients.elasticsearch.core.DeleteResponse;
+import co.elastic.clients.elasticsearch.core.IndexRequest;
+import co.elastic.clients.elasticsearch.core.IndexResponse;
+import co.elastic.clients.elasticsearch.indices.CreateIndexRequest;
+import co.elastic.clients.elasticsearch.indices.CreateIndexResponse;
+import co.elastic.clients.elasticsearch.indices.DeleteIndexRequest;
+import co.elastic.clients.elasticsearch.indices.DeleteIndexResponse;
+import co.elastic.clients.elasticsearch.indices.IndexSettings;
+import co.elastic.clients.elasticsearch.indices.IndexSettingsAnalysis;
import java.io.IOException;
+import java.util.List;
+import java.util.Map;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.core.persistence.api.entity.Any;
import org.apache.syncope.core.provisioning.api.event.AnyCreatedUpdatedEvent;
import org.apache.syncope.core.provisioning.api.event.AnyDeletedEvent;
import org.apache.syncope.core.spring.security.AuthContextUtils;
-import org.elasticsearch.ElasticsearchStatusException;
-import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
-import org.elasticsearch.action.delete.DeleteRequest;
-import org.elasticsearch.action.delete.DeleteResponse;
-import org.elasticsearch.action.get.GetRequest;
-import org.elasticsearch.action.get.GetResponse;
-import org.elasticsearch.action.index.IndexRequest;
-import org.elasticsearch.action.index.IndexResponse;
-import org.elasticsearch.action.support.master.AcknowledgedResponse;
-import org.elasticsearch.action.update.UpdateRequest;
-import org.elasticsearch.action.update.UpdateResponse;
-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.client.indices.GetIndexRequest;
-import org.elasticsearch.common.xcontent.XContentBuilder;
-import org.elasticsearch.common.xcontent.XContentFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.event.TransactionalEventListener;
@@ -53,12 +55,12 @@ public class ElasticsearchIndexManager {
private static final Logger LOG = LoggerFactory.getLogger(ElasticsearchIndexManager.class);
- protected final RestHighLevelClient client;
+ protected final ElasticsearchClient client;
protected final ElasticsearchUtils elasticsearchUtils;
public ElasticsearchIndexManager(
- final RestHighLevelClient client,
+ final ElasticsearchClient client,
final ElasticsearchUtils elasticsearchUtils) {
this.client = client;
@@ -67,127 +69,104 @@ public class ElasticsearchIndexManager {
public boolean existsIndex(final String domain, final AnyTypeKind kind) throws IOException {
return client.indices().exists(
- new GetIndexRequest(ElasticsearchUtils.getContextDomainName(domain, kind)), RequestOptions.DEFAULT);
+ new co.elastic.clients.elasticsearch.indices.ExistsRequest.Builder().
+ index(ElasticsearchUtils.getContextDomainName(domain, kind)).build()).
+ value();
}
- public XContentBuilder defaultSettings() throws IOException {
- return XContentFactory.jsonBuilder().
- startObject().
- startObject("analysis").
- startObject("normalizer").
- startObject("string_lowercase").
- field("type", "custom").
- field("char_filter", new Object[0]).
- field("filter").
- startArray().
- value("lowercase").
- endArray().
- endObject().
- endObject().
- endObject().
- startObject("index").
- field("number_of_shards", elasticsearchUtils.getNumberOfShards()).
- field("number_of_replicas", elasticsearchUtils.getNumberOfReplicas()).
- endObject().
- endObject();
+ public IndexSettings defaultSettings() throws IOException {
+ return new IndexSettings.Builder().
+ analysis(new IndexSettingsAnalysis.Builder().
+ normalizer("string_lowercase", new Normalizer.Builder().
+ custom(new CustomNormalizer.Builder().
+ charFilter(List.of()).
+ filter("lowercase").
+ build()).
+ build()).
+ build()).
+ numberOfShards(elasticsearchUtils.getNumberOfShards()).
+ numberOfReplicas(elasticsearchUtils.getNumberOfReplicas()).
+ build();
}
- public XContentBuilder defaultMapping() throws IOException {
- return XContentFactory.jsonBuilder().
- startObject().
- startArray("dynamic_templates").
- startObject().
- startObject("strings").
- field("match_mapping_type", "string").
- startObject("mapping").
- field("type", "keyword").
- field("normalizer", "string_lowercase").
- endObject().
- endObject().
- endObject().
- endArray().
- endObject();
+ public TypeMapping defaultMapping() throws IOException {
+ return new TypeMapping.Builder().
+ dynamicTemplates(List.of(Map.of(
+ "strings",
+ new DynamicTemplate.Builder().
+ matchMappingType("string").
+ mapping(new Property.Builder().
+ keyword(new KeywordProperty.Builder().normalizer("string_lowercase").build()).
+ build()).
+ build()))).
+ build();
}
protected CreateIndexResponse doCreateIndex(
final String domain,
final AnyTypeKind kind,
- final XContentBuilder settings,
- final XContentBuilder mapping) throws IOException {
+ final IndexSettings settings,
+ final TypeMapping mappings) throws IOException {
return client.indices().create(
- new CreateIndexRequest(ElasticsearchUtils.getContextDomainName(domain, kind)).
+ new CreateIndexRequest.Builder().
+ index(ElasticsearchUtils.getContextDomainName(domain, kind)).
settings(settings).
- mapping(mapping), RequestOptions.DEFAULT);
+ mappings(mappings).
+ build());
}
public void createIndex(
final String domain,
final AnyTypeKind kind,
- final XContentBuilder settings,
- final XContentBuilder mapping)
+ final IndexSettings settings,
+ final TypeMapping mappings)
throws IOException {
try {
- CreateIndexResponse response = doCreateIndex(domain, kind, settings, mapping);
+ CreateIndexResponse response = doCreateIndex(domain, kind, settings, mappings);
LOG.debug("Successfully created {} for {}: {}",
ElasticsearchUtils.getContextDomainName(domain, kind), kind.name(), response);
- } catch (ElasticsearchStatusException e) {
+ } catch (ElasticsearchException e) {
LOG.debug("Could not create index {} because it already exists",
ElasticsearchUtils.getContextDomainName(domain, kind), e);
removeIndex(domain, kind);
- doCreateIndex(domain, kind, settings, mapping);
+ doCreateIndex(domain, kind, settings, mappings);
}
}
public void removeIndex(final String domain, final AnyTypeKind kind) throws IOException {
- AcknowledgedResponse acknowledgedResponse = client.indices().delete(
- new DeleteIndexRequest(ElasticsearchUtils.getContextDomainName(domain, kind)), RequestOptions.DEFAULT);
+ DeleteIndexResponse response = client.indices().delete(
+ new DeleteIndexRequest.Builder().index(ElasticsearchUtils.getContextDomainName(domain, kind)).build());
LOG.debug("Successfully removed {}: {}",
- ElasticsearchUtils.getContextDomainName(domain, kind), acknowledgedResponse);
+ ElasticsearchUtils.getContextDomainName(domain, kind), response);
}
@TransactionalEventListener
public void after(final AnyCreatedUpdatedEvent<Any<?>> event) throws IOException {
- GetRequest getRequest = new GetRequest(
- ElasticsearchUtils.getContextDomainName(
- AuthContextUtils.getDomain(), event.getAny().getType().getKind()),
- event.getAny().getKey());
- GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT);
- if (getResponse.isExists()) {
- LOG.debug("About to update index for {}", event.getAny());
-
- UpdateRequest request = new UpdateRequest(
- ElasticsearchUtils.getContextDomainName(
- AuthContextUtils.getDomain(), event.getAny().getType().getKind()),
- event.getAny().getKey()).
- retryOnConflict(elasticsearchUtils.getRetryOnConflict()).
- doc(elasticsearchUtils.builder(event.getAny(), event.getDomain()));
- UpdateResponse response = client.update(request, RequestOptions.DEFAULT);
- LOG.debug("Index successfully updated for {}: {}", event.getAny(), response);
- } else {
- LOG.debug("About to create index for {}", event.getAny());
-
- IndexRequest request = new IndexRequest(
- ElasticsearchUtils.getContextDomainName(
- AuthContextUtils.getDomain(), event.getAny().getType().getKind())).
- id(event.getAny().getKey()).
- source(elasticsearchUtils.builder(event.getAny(), event.getDomain()));
- IndexResponse response = client.index(request, RequestOptions.DEFAULT);
- LOG.debug("Index successfully created for {}: {}", event.getAny(), response);
- }
+ String index = ElasticsearchUtils.getContextDomainName(
+ AuthContextUtils.getDomain(), event.getAny().getType().getKind());
+
+ IndexRequest<Map<String, Object>> request = new IndexRequest.Builder<Map<String, Object>>().
+ index(index).
+ id(event.getAny().getKey()).
+ document(elasticsearchUtils.document(event.getAny(), event.getDomain())).
+ build();
+ IndexResponse response = client.index(request);
+ LOG.debug("Index successfully created or updated for {}: {}", event.getAny(), response);
}
@TransactionalEventListener
public void after(final AnyDeletedEvent event) throws IOException {
LOG.debug("About to delete index for {}[{}]", event.getAnyTypeKind(), event.getAnyKey());
- DeleteRequest request = new DeleteRequest(
- ElasticsearchUtils.getContextDomainName(AuthContextUtils.getDomain(), event.getAnyTypeKind()),
- event.getAnyKey());
- DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
+ DeleteRequest request = new DeleteRequest.Builder().index(
+ ElasticsearchUtils.getContextDomainName(AuthContextUtils.getDomain(), event.getAnyTypeKind())).
+ id(event.getAnyKey()).
+ build();
+ DeleteResponse response = client.delete(request);
LOG.debug("Index successfully deleted for {}[{}]: {}",
event.getAnyTypeKind(), event.getAnyKey(), response);
}
diff --git a/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchUtils.java b/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchUtils.java
index 8ea8a24..54d2385 100644
--- a/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchUtils.java
+++ b/ext/elasticsearch/client-elasticsearch/src/main/java/org/apache/syncope/ext/elasticsearch/client/ElasticsearchUtils.java
@@ -21,8 +21,10 @@ package org.apache.syncope.ext.elasticsearch.client;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.syncope.common.lib.types.AnyTypeKind;
@@ -37,8 +39,6 @@ import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
import org.apache.syncope.core.persistence.api.entity.group.Group;
import org.apache.syncope.core.persistence.api.entity.user.User;
import org.apache.syncope.core.spring.security.AuthContextUtils;
-import org.elasticsearch.common.xcontent.XContentBuilder;
-import org.elasticsearch.common.xcontent.XContentFactory;
import org.springframework.transaction.annotation.Transactional;
/**
@@ -60,9 +60,9 @@ public class ElasticsearchUtils {
protected int retryOnConflict = 5;
- protected int numberOfShards = 1;
+ protected String numberOfShards = "1";
- protected int numberOfReplicas = 1;
+ protected String numberOfReplicas = "1";
public ElasticsearchUtils(final UserDAO userDAO, final GroupDAO groupDAO, final AnyObjectDAO anyObjectDAO) {
this.userDAO = userDAO;
@@ -86,32 +86,32 @@ public class ElasticsearchUtils {
return retryOnConflict;
}
- public int getNumberOfShards() {
+ public String getNumberOfShards() {
return numberOfShards;
}
public void setNumberOfShards(final int numberOfShards) {
- this.numberOfShards = numberOfShards;
+ this.numberOfShards = String.valueOf(numberOfShards);
}
- public int getNumberOfReplicas() {
+ public String getNumberOfReplicas() {
return numberOfReplicas;
}
public void setNumberOfReplicas(final int numberOfReplicas) {
- this.numberOfReplicas = numberOfReplicas;
+ this.numberOfReplicas = String.valueOf(numberOfReplicas);
}
/**
- * Returns the builder specialized with content from the provided any.
+ * Returns the document specialized with content from the provided any.
*
* @param any user, group or any object to index
* @param domain tenant information
- * @return builder specialized with content from the provided any
+ * @return document specialized with content from the provided any
* @throws IOException in case of errors
*/
@Transactional
- public XContentBuilder builder(final Any<?> any, final String domain) throws IOException {
+ public Map<String, Object> document(final Any<?> any, final String domain) throws IOException {
Set<String> resources = new HashSet<>();
List<String> dynRealms = new ArrayList<>();
AuthContextUtils.callAsAdmin(domain, () -> {
@@ -128,28 +128,27 @@ public class ElasticsearchUtils {
return null;
});
- XContentBuilder builder = XContentFactory.jsonBuilder().
- startObject().
- field("id", any.getKey()).
- field("realm", any.getRealm().getFullPath()).
- field("anyType", any.getType().getKey()).
- field("creationDate", any.getCreationDate()).
- field("creationContext", any.getCreationContext()).
- field("creator", any.getCreator()).
- field("lastChangeDate", any.getLastChangeDate()).
- field("lastModifier", any.getLastModifier()).
- field("lastChangeContext", any.getLastChangeContext()).
- field("status", any.getStatus()).
- field("resources", resources).
- field("dynRealms", dynRealms);
+ Map<String, Object> builder = new HashMap<>();
+ builder.put("id", any.getKey());
+ builder.put("realm", any.getRealm().getFullPath());
+ builder.put("anyType", any.getType().getKey());
+ builder.put("creationDate", any.getCreationDate());
+ builder.put("creationContext", any.getCreationContext());
+ builder.put("creator", any.getCreator());
+ builder.put("lastChangeDate", any.getLastChangeDate());
+ builder.put("lastModifier", any.getLastModifier());
+ builder.put("lastChangeContext", any.getLastChangeContext());
+ builder.put("status", any.getStatus());
+ builder.put("resources", resources);
+ builder.put("dynRealms", dynRealms);
if (any instanceof AnyObject) {
AnyObject anyObject = ((AnyObject) any);
- builder = builder.field("name", anyObject.getName());
+ builder.put("name", anyObject.getName());
Collection<String> memberships = AuthContextUtils.callAsAdmin(
domain, () -> anyObjectDAO.findAllGroupKeys(anyObject));
- builder = builder.field("memberships", memberships);
+ builder.put("memberships", memberships);
List<String> relationships = new ArrayList<>();
List<String> relationshipTypes = new ArrayList<>();
@@ -160,18 +159,18 @@ public class ElasticsearchUtils {
});
return null;
});
- builder = builder.field("relationships", relationships);
- builder = builder.field("relationshipTypes", relationshipTypes);
+ builder.put("relationships", relationships);
+ builder.put("relationshipTypes", relationshipTypes);
- builder = customizeBuilder(builder, anyObject, domain);
+ ElasticsearchUtils.this.customizeDocument(builder, anyObject, domain);
} else if (any instanceof Group) {
Group group = ((Group) any);
- builder = builder.field("name", group.getName());
+ builder.put("name", group.getName());
if (group.getUserOwner() != null) {
- builder = builder.field("userOwner", group.getUserOwner().getKey());
+ builder.put("userOwner", group.getUserOwner().getKey());
}
if (group.getGroupOwner() != null) {
- builder = builder.field("groupOwner", group.getGroupOwner().getKey());
+ builder.put("groupOwner", group.getGroupOwner().getKey());
}
Set<String> members = new HashSet<>();
@@ -184,20 +183,19 @@ public class ElasticsearchUtils {
members.addAll(groupDAO.findADynMembers(group));
return null;
});
- builder = builder.field("members", members);
+ builder.put("members", members);
- builder = customizeBuilder(builder, group, domain);
+ ElasticsearchUtils.this.customizeDocument(builder, group, domain);
} else if (any instanceof User) {
User user = ((User) any);
- builder = builder.
- field("username", user.getUsername()).
- field("token", user.getToken()).
- field("tokenExpireTime", user.getTokenExpireTime()).
- field("changePwdDate", user.getChangePwdDate()).
- field("failedLogins", user.getFailedLogins()).
- field("lastLoginDate", user.getLastLoginDate()).
- field("suspended", user.isSuspended()).
- field("mustChangePassword", user.isMustChangePassword());
+ builder.put("username", user.getUsername());
+ builder.put("token", user.getToken());
+ builder.put("tokenExpireTime", user.getTokenExpireTime());
+ builder.put("changePwdDate", user.getChangePwdDate());
+ builder.put("failedLogins", user.getFailedLogins());
+ builder.put("lastLoginDate", user.getLastLoginDate());
+ builder.put("suspended", user.isSuspended());
+ builder.put("mustChangePassword", user.isMustChangePassword());
List<String> roles = new ArrayList<>();
Set<String> privileges = new HashSet<>();
@@ -208,12 +206,12 @@ public class ElasticsearchUtils {
});
return null;
});
- builder = builder.field("roles", roles);
- builder = builder.field("privileges", privileges);
+ builder.put("roles", roles);
+ builder.put("privileges", privileges);
Collection<String> memberships = AuthContextUtils.callAsAdmin(
domain, () -> userDAO.findAllGroupKeys(user));
- builder = builder.field("memberships", memberships);
+ builder.put("memberships", memberships);
List<String> relationships = new ArrayList<>();
Set<String> relationshipTypes = new HashSet<>();
@@ -221,10 +219,10 @@ public class ElasticsearchUtils {
relationships.add(relationship.getRightEnd().getKey());
relationshipTypes.add(relationship.getType().getKey());
});
- builder = builder.field("relationships", relationships);
- builder = builder.field("relationshipTypes", relationshipTypes);
+ builder.put("relationships", relationships);
+ builder.put("relationshipTypes", relationshipTypes);
- builder = customizeBuilder(builder, user, domain);
+ customizeDocument(builder, user, domain);
}
for (PlainAttr<?> plainAttr : any.getPlainAttrs()) {
@@ -235,29 +233,23 @@ public class ElasticsearchUtils {
values.add(plainAttr.getUniqueValue().getValue());
}
- builder = builder.field(plainAttr.getSchema().getKey(), values.size() == 1 ? values.get(0) : values);
+ builder.put(plainAttr.getSchema().getKey(), values.size() == 1 ? values.get(0) : values);
}
- return builder.endObject();
+ return builder;
}
- protected XContentBuilder customizeBuilder(
- final XContentBuilder builder, final AnyObject anyObject, final String domain)
+ protected void customizeDocument(
+ final Map<String, Object> builder, final AnyObject anyObject, final String domain)
throws IOException {
-
- return builder;
}
- protected XContentBuilder customizeBuilder(
- final XContentBuilder builder, final Group group, final String domain)
+ protected void customizeDocument(
+ final Map<String, Object> builder, final Group group, final String domain)
throws IOException {
-
- return builder;
}
- protected XContentBuilder customizeBuilder(final XContentBuilder builder, final User user, final String domain)
+ protected void customizeDocument(final Map<String, Object> builder, final User user, final String domain)
throws IOException {
-
- return builder;
}
}
diff --git a/ext/elasticsearch/persistence-jpa/pom.xml b/ext/elasticsearch/persistence-jpa/pom.xml
index b9dcfcd..3c935e8 100644
--- a/ext/elasticsearch/persistence-jpa/pom.xml
+++ b/ext/elasticsearch/persistence-jpa/pom.xml
@@ -66,6 +66,11 @@ under the License.
<artifactId>mockito-junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
diff --git a/ext/elasticsearch/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/ElasticsearchPersistenceContext.java b/ext/elasticsearch/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/ElasticsearchPersistenceContext.java
index a869507..ccc8421 100644
--- a/ext/elasticsearch/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/ElasticsearchPersistenceContext.java
+++ b/ext/elasticsearch/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/ElasticsearchPersistenceContext.java
@@ -30,7 +30,7 @@ import org.apache.syncope.core.persistence.api.entity.EntityFactory;
import org.apache.syncope.core.persistence.jpa.dao.ElasticsearchAnySearchDAO;
import org.apache.syncope.ext.elasticsearch.client.ElasticsearchIndexManager;
import org.apache.syncope.ext.elasticsearch.client.ElasticsearchUtils;
-import org.elasticsearch.client.RestHighLevelClient;
+import co.elastic.clients.elasticsearch.ElasticsearchClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
@@ -59,7 +59,7 @@ public class ElasticsearchPersistenceContext {
final PlainSchemaDAO schemaDAO,
final EntityFactory entityFactory,
final AnyUtilsFactory anyUtilsFactory,
- final RestHighLevelClient client,
+ final ElasticsearchClient client,
final @Lazy ElasticsearchUtils elasticsearchUtils) {
return new ElasticsearchAnySearchDAO(
diff --git a/ext/elasticsearch/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/ElasticsearchAnySearchDAO.java b/ext/elasticsearch/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/ElasticsearchAnySearchDAO.java
index c2aaa9b..bd014ba 100644
--- a/ext/elasticsearch/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/ElasticsearchAnySearchDAO.java
+++ b/ext/elasticsearch/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/ElasticsearchAnySearchDAO.java
@@ -18,15 +18,29 @@
*/
package org.apache.syncope.core.persistence.jpa.dao;
+import co.elastic.clients.elasticsearch.ElasticsearchClient;
+import co.elastic.clients.elasticsearch._types.FieldSort;
+import co.elastic.clients.elasticsearch._types.FieldValue;
+import co.elastic.clients.elasticsearch._types.SearchType;
+import co.elastic.clients.elasticsearch._types.SortOptions;
+import co.elastic.clients.elasticsearch._types.SortOrder;
+import co.elastic.clients.elasticsearch._types.query_dsl.MatchAllQuery;
+import co.elastic.clients.elasticsearch._types.query_dsl.MatchNoneQuery;
+import co.elastic.clients.elasticsearch._types.query_dsl.Query;
+import co.elastic.clients.elasticsearch._types.query_dsl.QueryBuilders;
+import co.elastic.clients.elasticsearch.core.CountRequest;
+import co.elastic.clients.elasticsearch.core.SearchRequest;
+import co.elastic.clients.elasticsearch.core.search.Hit;
+import co.elastic.clients.json.JsonData;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
-import java.util.stream.Stream;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.lang3.tuple.Triple;
@@ -67,30 +81,18 @@ import org.apache.syncope.core.persistence.api.entity.Realm;
import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
import org.apache.syncope.core.spring.security.AuthContextUtils;
import org.apache.syncope.ext.elasticsearch.client.ElasticsearchUtils;
-import org.elasticsearch.action.search.SearchRequest;
-import org.elasticsearch.action.search.SearchType;
-import org.elasticsearch.client.RequestOptions;
-import org.elasticsearch.client.RestHighLevelClient;
-import org.elasticsearch.client.core.CountRequest;
-import org.elasticsearch.index.query.DisMaxQueryBuilder;
-import org.elasticsearch.index.query.MatchAllQueryBuilder;
-import org.elasticsearch.index.query.MatchNoneQueryBuilder;
-import org.elasticsearch.index.query.QueryBuilder;
-import org.elasticsearch.index.query.QueryBuilders;
-import org.elasticsearch.search.SearchHit;
-import org.elasticsearch.search.builder.SearchSourceBuilder;
-import org.elasticsearch.search.sort.FieldSortBuilder;
-import org.elasticsearch.search.sort.SortBuilder;
-import org.elasticsearch.search.sort.SortOrder;
+import org.springframework.util.CollectionUtils;
/**
* Search engine implementation for users, groups and any objects, based on Elasticsearch.
*/
public class ElasticsearchAnySearchDAO extends AbstractAnySearchDAO {
- protected static final QueryBuilder MATCH_NONE_QUERY_BUILDER = new MatchNoneQueryBuilder();
+ protected static final Query MATCH_NONE_QUERY =
+ new Query.Builder().matchNone(new MatchNoneQuery.Builder().build()).build();
- protected static final QueryBuilder MATCH_ALL_QUERY_BUILDER = new MatchAllQueryBuilder();
+ protected static final Query MATCH_ALL_QUERY =
+ new Query.Builder().matchAll(new MatchAllQuery.Builder().build()).build();
protected static final char[] ELASTICSEARCH_REGEX_CHARS = new char[] {
'.', '?', '+', '*', '|', '{', '}', '[', ']', '(', ')', '"', '\\', '&' };
@@ -107,7 +109,7 @@ public class ElasticsearchAnySearchDAO extends AbstractAnySearchDAO {
return output.toString();
}
- protected final RestHighLevelClient client;
+ protected final ElasticsearchClient client;
protected final ElasticsearchUtils elasticsearchUtils;
@@ -120,7 +122,7 @@ public class ElasticsearchAnySearchDAO extends AbstractAnySearchDAO {
final PlainSchemaDAO schemaDAO,
final EntityFactory entityFactory,
final AnyUtilsFactory anyUtilsFactory,
- final RestHighLevelClient client,
+ final ElasticsearchClient client,
final ElasticsearchUtils elasticsearchUtils) {
super(realmDAO, dynRealmDAO, userDAO, groupDAO, anyObjectDAO, schemaDAO, entityFactory, anyUtilsFactory);
@@ -128,13 +130,12 @@ public class ElasticsearchAnySearchDAO extends AbstractAnySearchDAO {
this.elasticsearchUtils = elasticsearchUtils;
}
- protected Triple<Optional<QueryBuilder>, Set<String>, Set<String>> getAdminRealmsFilter(
+ protected Triple<Optional<Query>, Set<String>, Set<String>> getAdminRealmsFilter(
final AnyTypeKind kind, final Set<String> adminRealms) {
- DisMaxQueryBuilder builder = QueryBuilders.disMaxQuery();
-
Set<String> dynRealmKeys = new HashSet<>();
Set<String> groupOwners = new HashSet<>();
+ List<Query> queries = new ArrayList<>();
adminRealms.forEach(realmPath -> {
Optional<Pair<String, String>> goRealm = RealmUtils.parseGroupOwnerRealm(realmPath);
@@ -147,8 +148,10 @@ public class ElasticsearchAnySearchDAO extends AbstractAnySearchDAO {
noRealm.getElements().add("Invalid realm specified: " + realmPath);
throw noRealm;
} else {
- realmDAO.findDescendants(realm).forEach(
- descendant -> builder.add(QueryBuilders.termQuery("realm", descendant.getFullPath())));
+ realmDAO.findDescendants(realm).forEach(descendant -> queries.add(
+ new Query.Builder().term(QueryBuilders.term().
+ field("realm").value(FieldValue.of(descendant.getFullPath())).build()).
+ build()));
}
} else {
DynRealm dynRealm = dynRealmDAO.find(realmPath);
@@ -156,59 +159,66 @@ public class ElasticsearchAnySearchDAO extends AbstractAnySearchDAO {
LOG.warn("Ignoring invalid dynamic realm {}", realmPath);
} else {
dynRealmKeys.add(dynRealm.getKey());
- builder.add(QueryBuilders.termQuery("dynRealm", dynRealm.getKey()));
+ queries.add(new Query.Builder().term(QueryBuilders.term().
+ field("dynRealm").value(FieldValue.of(dynRealm.getKey())).build()).
+ build());
}
}
});
return Triple.of(
- dynRealmKeys.isEmpty() && groupOwners.isEmpty() ? Optional.of(builder) : Optional.empty(),
+ dynRealmKeys.isEmpty() && groupOwners.isEmpty()
+ ? Optional.of(new Query.Builder().disMax(QueryBuilders.disMax().queries(queries).build()).build())
+ : Optional.empty(),
dynRealmKeys,
groupOwners);
}
- protected QueryBuilder getQueryBuilder(
+ protected Query getQuery(
final Set<String> adminRealms,
final SearchCond cond,
final AnyTypeKind kind) {
- Triple<Optional<QueryBuilder>, Set<String>, Set<String>> filter = getAdminRealmsFilter(kind, adminRealms);
- QueryBuilder queryBuilder;
+ Triple<Optional<Query>, Set<String>, Set<String>> filter = getAdminRealmsFilter(kind, adminRealms);
+ Query query;
if (SyncopeConstants.FULL_ADMIN_REALMS.equals(adminRealms)) {
- queryBuilder = getQueryBuilder(cond, kind);
+ query = getQuery(cond, kind);
} else {
- queryBuilder = getQueryBuilder(buildEffectiveCond(cond, filter.getMiddle(), filter.getRight(), kind), kind);
+ query = getQuery(buildEffectiveCond(cond, filter.getMiddle(), filter.getRight(), kind), kind);
if (filter.getLeft().isPresent()) {
- queryBuilder = QueryBuilders.boolQuery().
- must(filter.getLeft().get()).
- must(queryBuilder);
+ query = new Query.Builder().bool(
+ QueryBuilders.bool().
+ must(filter.getLeft().get()).
+ must(query).build()).
+ build();
}
}
- return queryBuilder;
+ return query;
}
@Override
protected int doCount(final Set<String> adminRealms, final SearchCond cond, final AnyTypeKind kind) {
- CountRequest request = new CountRequest(
- ElasticsearchUtils.getContextDomainName(AuthContextUtils.getDomain(), kind)).
- query(getQueryBuilder(adminRealms, cond, kind));
+ CountRequest request = new CountRequest.Builder().
+ index(ElasticsearchUtils.getContextDomainName(AuthContextUtils.getDomain(), kind)).
+ query(getQuery(adminRealms, cond, kind)).
+ build();
try {
- return (int) client.count(request, RequestOptions.DEFAULT).getCount();
+ return (int) client.count(request).count();
} catch (IOException e) {
LOG.error("Search error", e);
return 0;
}
}
- protected List<SortBuilder<?>> sortBuilders(
+ protected List<SortOptions> sortBuilders(
final AnyTypeKind kind,
final List<OrderByClause> orderBy) {
AnyUtils anyUtils = anyUtilsFactory.getInstance(kind);
- List<SortBuilder<?>> builders = new ArrayList<>();
+ List<SortOptions> options = new ArrayList<>();
orderBy.forEach(clause -> {
String sortName = null;
@@ -228,10 +238,16 @@ public class ElasticsearchAnySearchDAO extends AbstractAnySearchDAO {
if (sortName == null) {
LOG.warn("Cannot build any valid clause from {}", clause);
} else {
- builders.add(new FieldSortBuilder(sortName).order(SortOrder.valueOf(clause.getDirection().name())));
+ options.add(new SortOptions.Builder().field(
+ new FieldSort.Builder().
+ field(sortName).
+ order(clause.getDirection() == OrderByClause.Direction.ASC
+ ? SortOrder.Asc : SortOrder.Desc).
+ build()).
+ build());
}
});
- return builders;
+ return options;
}
@Override
@@ -243,229 +259,252 @@ public class ElasticsearchAnySearchDAO extends AbstractAnySearchDAO {
final List<OrderByClause> orderBy,
final AnyTypeKind kind) {
- SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().
- query(getQueryBuilder(adminRealms, cond, kind)).
+ SearchRequest request = new SearchRequest.Builder().
+ index(ElasticsearchUtils.getContextDomainName(AuthContextUtils.getDomain(), kind)).
+ searchType(SearchType.QueryThenFetch).
+ query(getQuery(adminRealms, cond, kind)).
from(itemsPerPage * (page <= 0 ? 0 : page - 1)).
- size(itemsPerPage < 0 ? elasticsearchUtils.getIndexMaxResultWindow() : itemsPerPage);
- sortBuilders(kind, orderBy).forEach(sourceBuilder::sort);
-
- SearchRequest request = new SearchRequest(
- ElasticsearchUtils.getContextDomainName(AuthContextUtils.getDomain(), kind)).
- searchType(SearchType.QUERY_THEN_FETCH).
- source(sourceBuilder);
+ size(itemsPerPage < 0 ? elasticsearchUtils.getIndexMaxResultWindow() : itemsPerPage).
+ sort(sortBuilders(kind, orderBy)).
+ build();
- SearchHit[] esResult = null;
+ @SuppressWarnings("rawtypes")
+ List<Hit<Map>> esResult = null;
try {
- esResult = client.search(request, RequestOptions.DEFAULT).getHits().getHits();
+ esResult = client.search(request, Map.class).hits().hits();
} catch (Exception e) {
LOG.error("While searching in Elasticsearch", e);
}
- return ArrayUtils.isEmpty(esResult)
+ return CollectionUtils.isEmpty(esResult)
? List.of()
- : buildResult(Stream.of(esResult).map(SearchHit::getId).collect(Collectors.toList()), kind);
+ : buildResult(esResult.stream().map(Hit::id).collect(Collectors.toList()), kind);
}
- protected QueryBuilder getQueryBuilder(final SearchCond cond, final AnyTypeKind kind) {
- QueryBuilder builder = null;
+ protected Query getQuery(final SearchCond cond, final AnyTypeKind kind) {
+ Query query = null;
switch (cond.getType()) {
case LEAF:
case NOT_LEAF:
- builder = cond.getLeaf(AnyTypeCond.class).
+ query = cond.getLeaf(AnyTypeCond.class).
filter(leaf -> AnyTypeKind.ANY_OBJECT == kind).
- map(this::getQueryBuilder).
+ map(this::getQuery).
orElse(null);
- if (builder == null) {
- builder = cond.getLeaf(RelationshipTypeCond.class).
+ if (query == null) {
+ query = cond.getLeaf(RelationshipTypeCond.class).
filter(leaf -> AnyTypeKind.GROUP != kind).
- map(this::getQueryBuilder).
+ map(this::getQuery).
orElse(null);
}
- if (builder == null) {
- builder = cond.getLeaf(RelationshipCond.class).
+ if (query == null) {
+ query = cond.getLeaf(RelationshipCond.class).
filter(leaf -> AnyTypeKind.GROUP != kind).
- map(this::getQueryBuilder).
+ map(this::getQuery).
orElse(null);
}
- if (builder == null) {
- builder = cond.getLeaf(MembershipCond.class).
+ if (query == null) {
+ query = cond.getLeaf(MembershipCond.class).
filter(leaf -> AnyTypeKind.GROUP != kind).
- map(this::getQueryBuilder).
+ map(this::getQuery).
orElse(null);
}
- if (builder == null) {
- builder = cond.getLeaf(MemberCond.class).
+ if (query == null) {
+ query = cond.getLeaf(MemberCond.class).
filter(leaf -> AnyTypeKind.GROUP == kind).
- map(this::getQueryBuilder).
+ map(this::getQuery).
orElse(null);
}
- if (builder == null) {
- builder = cond.getLeaf(AssignableCond.class).
- map(this::getQueryBuilder).
+ if (query == null) {
+ query = cond.getLeaf(AssignableCond.class).
+ map(this::getQuery).
orElse(null);
}
- if (builder == null) {
- builder = cond.getLeaf(RoleCond.class).
+ if (query == null) {
+ query = cond.getLeaf(RoleCond.class).
filter(leaf -> AnyTypeKind.USER == kind).
- map(this::getQueryBuilder).
+ map(this::getQuery).
orElse(null);
}
- if (builder == null) {
- builder = cond.getLeaf(PrivilegeCond.class).
+ if (query == null) {
+ query = cond.getLeaf(PrivilegeCond.class).
filter(leaf -> AnyTypeKind.USER == kind).
- map(this::getQueryBuilder).
+ map(this::getQuery).
orElse(null);
}
- if (builder == null) {
- builder = cond.getLeaf(DynRealmCond.class).
- map(this::getQueryBuilder).
+ if (query == null) {
+ query = cond.getLeaf(DynRealmCond.class).
+ map(this::getQuery).
orElse(null);
}
- if (builder == null) {
- builder = cond.getLeaf(ResourceCond.class).
- map(this::getQueryBuilder).
+ if (query == null) {
+ query = cond.getLeaf(ResourceCond.class).
+ map(this::getQuery).
orElse(null);
}
- if (builder == null) {
+ if (query == null) {
Optional<AnyCond> anyCond = cond.getLeaf(AnyCond.class);
if (anyCond.isPresent()) {
- builder = getQueryBuilder(anyCond.get(), kind);
+ query = getQuery(anyCond.get(), kind);
} else {
- builder = cond.getLeaf(AttrCond.class).
- map(leaf -> getQueryBuilder(leaf, kind)).
+ query = cond.getLeaf(AttrCond.class).
+ map(leaf -> getQuery(leaf, kind)).
orElse(null);
}
}
// allow for additional search conditions
- if (builder == null) {
- builder = getQueryBuilderForCustomConds(cond, kind);
+ if (query == null) {
+ query = getQueryForCustomConds(cond, kind);
}
- if (builder == null) {
- builder = MATCH_NONE_QUERY_BUILDER;
+ if (query == null) {
+ query = MATCH_NONE_QUERY;
}
if (cond.getType() == SearchCond.Type.NOT_LEAF) {
- builder = QueryBuilders.boolQuery().mustNot(builder);
+ query = new Query.Builder().bool(QueryBuilders.bool().mustNot(query).build()).build();
}
break;
case AND:
- builder = QueryBuilders.boolQuery().
- must(getQueryBuilder(cond.getLeft(), kind)).
- must(getQueryBuilder(cond.getRight(), kind));
+ query = new Query.Builder().bool(QueryBuilders.bool().
+ must(getQuery(cond.getLeft(), kind)).must(getQuery(cond.getRight(), kind)).build()).
+ build();
break;
case OR:
- builder = QueryBuilders.disMaxQuery().
- add(getQueryBuilder(cond.getLeft(), kind)).
- add(getQueryBuilder(cond.getRight(), kind));
+ query = new Query.Builder().disMax(QueryBuilders.disMax().
+ queries(getQuery(cond.getLeft(), kind), getQuery(cond.getRight(), kind)).build()).
+ build();
break;
default:
}
- return builder;
+ return query;
}
- protected QueryBuilder getQueryBuilder(final AnyTypeCond cond) {
- return QueryBuilders.termQuery("anyType", cond.getAnyTypeKey());
+ protected Query getQuery(final AnyTypeCond cond) {
+ return new Query.Builder().term(QueryBuilders.term().
+ field("anyType").value(FieldValue.of(cond.getAnyTypeKey())).build()).
+ build();
}
- protected QueryBuilder getQueryBuilder(final RelationshipTypeCond cond) {
- return QueryBuilders.termQuery("relationshipTypes", cond.getRelationshipTypeKey());
+ protected Query getQuery(final RelationshipTypeCond cond) {
+ return new Query.Builder().term(QueryBuilders.term().
+ field("relationshipTypes").value(FieldValue.of(cond.getRelationshipTypeKey())).build()).
+ build();
}
- protected QueryBuilder getQueryBuilder(final RelationshipCond cond) {
+ protected Query getQuery(final RelationshipCond cond) {
String rightAnyObjectKey;
try {
rightAnyObjectKey = check(cond);
} catch (IllegalArgumentException e) {
- return MATCH_NONE_QUERY_BUILDER;
+ return MATCH_NONE_QUERY;
}
- return QueryBuilders.termQuery("relationships", rightAnyObjectKey);
+ return new Query.Builder().term(QueryBuilders.term().
+ field("relationships").value(FieldValue.of(rightAnyObjectKey)).build()).
+ build();
}
- protected QueryBuilder getQueryBuilder(final MembershipCond cond) {
+ protected Query getQuery(final MembershipCond cond) {
List<String> groupKeys;
try {
groupKeys = check(cond);
} catch (IllegalArgumentException e) {
- return MATCH_NONE_QUERY_BUILDER;
+ return MATCH_NONE_QUERY;
}
- if (groupKeys.size() == 1) {
- return QueryBuilders.termQuery("memberships", groupKeys.get(0));
+ List<Query> membershipQueries = groupKeys.stream().
+ map(key -> new Query.Builder().term(QueryBuilders.term().
+ field("memberships").value(FieldValue.of(key)).build()).
+ build()).collect(Collectors.toList());
+ if (membershipQueries.size() == 1) {
+ return membershipQueries.get(0);
}
- DisMaxQueryBuilder builder = QueryBuilders.disMaxQuery();
- groupKeys.forEach(key -> builder.add(QueryBuilders.termQuery("memberships", key)));
- return builder;
+ return new Query.Builder().disMax(QueryBuilders.disMax().queries(membershipQueries).build()).build();
}
- protected QueryBuilder getQueryBuilder(final AssignableCond cond) {
+ protected Query getQuery(final AssignableCond cond) {
Realm realm;
try {
realm = check(cond);
} catch (IllegalArgumentException e) {
- return MATCH_NONE_QUERY_BUILDER;
+ return MATCH_NONE_QUERY;
}
- DisMaxQueryBuilder builder = QueryBuilders.disMaxQuery();
+ List<Query> queries = new ArrayList<>();
if (cond.isFromGroup()) {
realmDAO.findDescendants(realm).forEach(
- current -> builder.add(QueryBuilders.termQuery("realm", current.getFullPath())));
+ current -> queries.add(new Query.Builder().term(QueryBuilders.term().
+ field("realm").value(FieldValue.of(current.getFullPath())).build()).
+ build()));
} else {
for (Realm current = realm; current.getParent() != null; current = current.getParent()) {
- builder.add(QueryBuilders.termQuery("realm", current.getFullPath()));
+ queries.add(new Query.Builder().term(QueryBuilders.term().
+ field("realm").value(FieldValue.of(current.getFullPath())).build()).
+ build());
}
- builder.add(QueryBuilders.termQuery("realm", realmDAO.getRoot().getFullPath()));
+ queries.add(new Query.Builder().term(QueryBuilders.term().
+ field("realm").value(FieldValue.of(realmDAO.getRoot().getFullPath())).build()).
+ build());
}
- return builder;
+ return new Query.Builder().disMax(QueryBuilders.disMax().queries(queries).build()).build();
}
- protected QueryBuilder getQueryBuilder(final RoleCond cond) {
- return QueryBuilders.termQuery("roles", cond.getRole());
+ protected Query getQuery(final RoleCond cond) {
+ return new Query.Builder().term(QueryBuilders.term().
+ field("roles").value(FieldValue.of(cond.getRole())).build()).
+ build();
}
- protected QueryBuilder getQueryBuilder(final PrivilegeCond cond) {
- return QueryBuilders.termQuery("privileges", cond.getPrivilege());
+ protected Query getQuery(final PrivilegeCond cond) {
+ return new Query.Builder().term(QueryBuilders.term().
+ field("privileges").value(FieldValue.of(cond.getPrivilege())).build()).
+ build();
}
- protected QueryBuilder getQueryBuilder(final DynRealmCond cond) {
- return QueryBuilders.termQuery("dynRealms", cond.getDynRealm());
+ protected Query getQuery(final DynRealmCond cond) {
+ return new Query.Builder().term(QueryBuilders.term().
+ field("dynRealms").value(FieldValue.of(cond.getDynRealm())).build()).
+ build();
}
- protected QueryBuilder getQueryBuilder(final MemberCond cond) {
+ protected Query getQuery(final MemberCond cond) {
String memberKey;
try {
memberKey = check(cond);
} catch (IllegalArgumentException e) {
- return MATCH_NONE_QUERY_BUILDER;
+ return MATCH_NONE_QUERY;
}
- return QueryBuilders.termQuery("members", memberKey);
+ return new Query.Builder().term(QueryBuilders.term().
+ field("members").value(FieldValue.of(memberKey)).build()).
+ build();
}
- protected QueryBuilder getQueryBuilder(final ResourceCond cond) {
- return QueryBuilders.termQuery("resources", cond.getResourceKey());
+ protected Query getQuery(final ResourceCond cond) {
+ return new Query.Builder().term(QueryBuilders.term().
+ field("resources").value(FieldValue.of(cond.getResourceKey())).build()).
+ build();
}
- protected QueryBuilder fillAttrQuery(
+ protected Query fillAttrQuery(
final PlainSchema schema,
final PlainAttrValue attrValue,
final AttrCond cond) {
@@ -474,15 +513,17 @@ public class ElasticsearchAnySearchDAO extends AbstractAnySearchDAO {
? attrValue.getDateValue().getTime()
: attrValue.getValue();
- QueryBuilder builder = MATCH_NONE_QUERY_BUILDER;
+ Query query = MATCH_NONE_QUERY;
switch (cond.getType()) {
case ISNOTNULL:
- builder = QueryBuilders.existsQuery(schema.getKey());
+ query = new Query.Builder().exists(QueryBuilders.exists().field(schema.getKey()).build()).build();
break;
case ISNULL:
- builder = QueryBuilders.boolQuery().mustNot(QueryBuilders.existsQuery(schema.getKey()));
+ query = new Query.Builder().bool(QueryBuilders.bool().mustNot(
+ new Query.Builder().exists(QueryBuilders.exists().field(schema.getKey()).build()).build()).
+ build()).build();
break;
case ILIKE:
@@ -499,62 +540,86 @@ public class ElasticsearchAnySearchDAO extends AbstractAnySearchDAO {
output.append(escapeForLikeRegex(c));
}
}
- builder = QueryBuilders.regexpQuery(schema.getKey(), output.toString());
+ query = new Query.Builder().regexp(QueryBuilders.regexp().
+ field(schema.getKey()).value(output.toString()).build()).build();
break;
case LIKE:
- builder = QueryBuilders.wildcardQuery(schema.getKey(), cond.getExpression().replace('%', '*'));
+ query = new Query.Builder().wildcard(QueryBuilders.wildcard().
+ field(schema.getKey()).value(cond.getExpression().replace('%', '*')).build()).build();
break;
case IEQ:
- builder = QueryBuilders.matchQuery(schema.getKey(), cond.getExpression().toLowerCase());
+ query = new Query.Builder().match(QueryBuilders.match().
+ field(schema.getKey()).query(FieldValue.of(cond.getExpression().toLowerCase())).build()).
+ build();
break;
case EQ:
- builder = QueryBuilders.termQuery(schema.getKey(), value);
+ FieldValue fieldValue;
+ if (value instanceof Double) {
+ fieldValue = FieldValue.of((Double) value);
+ } else if (value instanceof Long) {
+ fieldValue = FieldValue.of((Long) value);
+ } else if (value instanceof Boolean) {
+ fieldValue = FieldValue.of((Boolean) value);
+ } else {
+ fieldValue = FieldValue.of(value.toString());
+ }
+ query = new Query.Builder().term(QueryBuilders.term().
+ field(schema.getKey()).value(fieldValue).build()).
+ build();
break;
case GE:
- builder = QueryBuilders.rangeQuery(schema.getKey()).gte(value);
+ query = new Query.Builder().range(QueryBuilders.range().
+ field(schema.getKey()).gte(JsonData.of(value)).build()).
+ build();
break;
case GT:
- builder = QueryBuilders.rangeQuery(schema.getKey()).gt(value);
+ query = new Query.Builder().range(QueryBuilders.range().
+ field(schema.getKey()).gt(JsonData.of(value)).build()).
+ build();
break;
case LE:
- builder = QueryBuilders.rangeQuery(schema.getKey()).lte(value);
+ query = new Query.Builder().range(QueryBuilders.range().
+ field(schema.getKey()).lte(JsonData.of(value)).build()).
+ build();
break;
case LT:
- builder = QueryBuilders.rangeQuery(schema.getKey()).lt(value);
+ query = new Query.Builder().range(QueryBuilders.range().
+ field(schema.getKey()).lt(JsonData.of(value)).build()).
+ build();
break;
default:
}
- return builder;
+ return query;
}
- protected QueryBuilder getQueryBuilder(final AttrCond cond, final AnyTypeKind kind) {
+ protected Query getQuery(final AttrCond cond, final AnyTypeKind kind) {
Pair<PlainSchema, PlainAttrValue> checked;
try {
checked = check(cond, kind);
} catch (IllegalArgumentException e) {
- return MATCH_NONE_QUERY_BUILDER;
+ return MATCH_NONE_QUERY;
}
return fillAttrQuery(checked.getLeft(), checked.getRight(), cond);
}
- protected QueryBuilder getQueryBuilder(final AnyCond cond, final AnyTypeKind kind) {
+ protected Query getQuery(final AnyCond cond, final AnyTypeKind kind) {
if (JAXRSService.PARAM_REALM.equals(cond.getSchema())
&& SyncopeConstants.UUID_PATTERN.matcher(cond.getExpression()).matches()) {
Realm realm = realmDAO.find(cond.getExpression());
if (realm == null) {
LOG.warn("Invalid Realm key: {}", cond.getExpression());
- return MATCH_NONE_QUERY_BUILDER;
+ return MATCH_NONE_QUERY;
}
cond.setExpression(realm.getFullPath());
}
@@ -563,13 +628,13 @@ public class ElasticsearchAnySearchDAO extends AbstractAnySearchDAO {
try {
checked = check(cond, kind);
} catch (IllegalArgumentException e) {
- return MATCH_NONE_QUERY_BUILDER;
+ return MATCH_NONE_QUERY;
}
return fillAttrQuery(checked.getLeft(), checked.getMiddle(), checked.getRight());
}
- protected QueryBuilder getQueryBuilderForCustomConds(final SearchCond cond, final AnyTypeKind kind) {
- return MATCH_ALL_QUERY_BUILDER;
+ protected Query getQueryForCustomConds(final SearchCond cond, final AnyTypeKind kind) {
+ return MATCH_ALL_QUERY;
}
}
diff --git a/ext/elasticsearch/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/dao/ElasticsearchAnySearchDAOTest.java b/ext/elasticsearch/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/dao/ElasticsearchAnySearchDAOTest.java
index 2fa9a54..770cb76 100644
--- a/ext/elasticsearch/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/dao/ElasticsearchAnySearchDAOTest.java
+++ b/ext/elasticsearch/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/dao/ElasticsearchAnySearchDAOTest.java
@@ -18,11 +18,17 @@
*/
package org.apache.syncope.core.persistence.jpa.dao;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
+import co.elastic.clients.elasticsearch._types.FieldValue;
+import co.elastic.clients.elasticsearch._types.SearchType;
+import co.elastic.clients.elasticsearch._types.query_dsl.Query;
+import co.elastic.clients.elasticsearch._types.query_dsl.QueryBuilders;
+import co.elastic.clients.elasticsearch.core.SearchRequest;
import java.io.IOException;
import java.util.List;
import java.util.Optional;
@@ -48,11 +54,6 @@ import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser;
import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
import org.apache.syncope.core.spring.security.AuthContextUtils;
import org.apache.syncope.ext.elasticsearch.client.ElasticsearchUtils;
-import org.elasticsearch.action.search.SearchRequest;
-import org.elasticsearch.action.search.SearchType;
-import org.elasticsearch.index.query.QueryBuilder;
-import org.elasticsearch.index.query.QueryBuilders;
-import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
@@ -87,7 +88,7 @@ public class ElasticsearchAnySearchDAOTest {
private ElasticsearchAnySearchDAO searchDAO;
@Test
- public void getAdminRealmsFilter_realm() {
+ public void getAdminRealmsFilter_realm() throws IOException {
// 1. mock
Realm root = mock(Realm.class);
when(root.getFullPath()).thenReturn(SyncopeConstants.ROOT_REALM);
@@ -97,11 +98,15 @@ public class ElasticsearchAnySearchDAOTest {
// 2. test
Set<String> adminRealms = Set.of(SyncopeConstants.ROOT_REALM);
- Triple<Optional<QueryBuilder>, Set<String>, Set<String>> filter =
+ Triple<Optional<Query>, Set<String>, Set<String>> filter =
searchDAO.getAdminRealmsFilter(AnyTypeKind.USER, adminRealms);
- assertEquals(
- QueryBuilders.disMaxQuery().add(QueryBuilders.termQuery("realm", SyncopeConstants.ROOT_REALM)),
- filter.getLeft().get());
+
+ assertThat(
+ new Query.Builder().disMax(QueryBuilders.disMax().queries(
+ new Query.Builder().term(QueryBuilders.term().field("realm").value(
+ FieldValue.of(SyncopeConstants.ROOT_REALM)).build()).build()).build()).
+ build()).
+ usingRecursiveComparison().isEqualTo(filter.getLeft().get());
assertEquals(Set.of(), filter.getMiddle());
assertEquals(Set.of(), filter.getRight());
}
@@ -116,7 +121,7 @@ public class ElasticsearchAnySearchDAOTest {
// 2. test
Set<String> adminRealms = Set.of("dyn");
- Triple<Optional<QueryBuilder>, Set<String>, Set<String>> filter =
+ Triple<Optional<Query>, Set<String>, Set<String>> filter =
searchDAO.getAdminRealmsFilter(AnyTypeKind.USER, adminRealms);
assertFalse(filter.getLeft().isPresent());
assertEquals(Set.of("dyn"), filter.getMiddle());
@@ -126,7 +131,7 @@ public class ElasticsearchAnySearchDAOTest {
@Test
public void getAdminRealmsFilter_groupOwner() {
Set<String> adminRealms = Set.of(RealmUtils.getGroupOwnerRealm("/any", "groupKey"));
- Triple<Optional<QueryBuilder>, Set<String>, Set<String>> filter =
+ Triple<Optional<Query>, Set<String>, Set<String>> filter =
searchDAO.getAdminRealmsFilter(AnyTypeKind.USER, adminRealms);
assertFalse(filter.getLeft().isPresent());
assertEquals(Set.of(), filter.getMiddle());
@@ -156,22 +161,21 @@ public class ElasticsearchAnySearchDAOTest {
AnyCond anyCond = new AnyCond(AttrCond.Type.ISNOTNULL);
anyCond.setSchema("id");
- SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().
- query(searchDAO.getQueryBuilder(adminRealms, SearchCond.getLeaf(anyCond), AnyTypeKind.USER)).
+ SearchRequest request = new SearchRequest.Builder().
+ index(ElasticsearchUtils.getContextDomainName(AuthContextUtils.getDomain(), AnyTypeKind.USER)).
+ searchType(SearchType.QueryThenFetch).
+ query(searchDAO.getQuery(adminRealms, SearchCond.getLeaf(anyCond), AnyTypeKind.USER)).
from(1).
- size(10);
- searchDAO.sortBuilders(AnyTypeKind.USER, List.of()).forEach(sourceBuilder::sort);
-
- SearchRequest request = new SearchRequest(
- ElasticsearchUtils.getContextDomainName(AuthContextUtils.getDomain(), AnyTypeKind.USER)).
- searchType(SearchType.QUERY_THEN_FETCH).
- source(sourceBuilder);
-
- assertEquals(
- QueryBuilders.boolQuery().
- must(QueryBuilders.existsQuery("id")).
- must(QueryBuilders.termQuery("memberships", "groupKey")),
- request.source().query());
+ size(10).
+ build();
+
+ assertThat(
+ new Query.Builder().bool(QueryBuilders.bool().
+ must(new Query.Builder().exists(QueryBuilders.exists().field("id").build()).build()).
+ must(new Query.Builder().term(QueryBuilders.term().field("memberships").value(
+ FieldValue.of("groupKey")).build()).build()).
+ build()).build()).
+ usingRecursiveComparison().isEqualTo(request.query());
}
}
}
diff --git a/ext/elasticsearch/provisioning-java/pom.xml b/ext/elasticsearch/provisioning-java/pom.xml
index ef60198..bd1d9c8 100644
--- a/ext/elasticsearch/provisioning-java/pom.xml
+++ b/ext/elasticsearch/provisioning-java/pom.xml
@@ -43,7 +43,7 @@ under the License.
<artifactId>syncope-core-provisioning-java</artifactId>
<version>${project.version}</version>
</dependency>
-
+
<dependency>
<groupId>org.apache.syncope.ext.elasticsearch</groupId>
<artifactId>syncope-ext-elasticsearch-client</artifactId>
diff --git a/ext/elasticsearch/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/ElasticsearchReindex.java b/ext/elasticsearch/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/ElasticsearchReindex.java
index 6ae2d34..f7ef590 100644
--- a/ext/elasticsearch/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/ElasticsearchReindex.java
+++ b/ext/elasticsearch/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/ElasticsearchReindex.java
@@ -18,7 +18,13 @@
*/
package org.apache.syncope.core.provisioning.java.job;
+import co.elastic.clients.elasticsearch.ElasticsearchClient;
+import co.elastic.clients.elasticsearch._types.mapping.TypeMapping;
+import co.elastic.clients.elasticsearch.core.IndexRequest;
+import co.elastic.clients.elasticsearch.core.IndexResponse;
+import co.elastic.clients.elasticsearch.indices.IndexSettings;
import java.io.IOException;
+import java.util.Map;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.core.persistence.api.dao.AnyDAO;
import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
@@ -28,11 +34,6 @@ import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
import org.apache.syncope.core.spring.security.AuthContextUtils;
import org.apache.syncope.ext.elasticsearch.client.ElasticsearchIndexManager;
import org.apache.syncope.ext.elasticsearch.client.ElasticsearchUtils;
-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.common.xcontent.XContentBuilder;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
@@ -43,7 +44,7 @@ import org.springframework.beans.factory.annotation.Autowired;
public class ElasticsearchReindex extends AbstractSchedTaskJobDelegate {
@Autowired
- protected RestHighLevelClient client;
+ protected ElasticsearchClient client;
@Autowired
protected ElasticsearchIndexManager indexManager;
@@ -60,27 +61,27 @@ public class ElasticsearchReindex extends AbstractSchedTaskJobDelegate {
@Autowired
protected AnyObjectDAO anyObjectDAO;
- protected XContentBuilder userSettings() throws IOException {
+ protected IndexSettings userSettings() throws IOException {
return indexManager.defaultSettings();
}
- protected XContentBuilder groupSettings() throws IOException {
+ protected IndexSettings groupSettings() throws IOException {
return indexManager.defaultSettings();
}
- protected XContentBuilder anyObjectSettings() throws IOException {
+ protected IndexSettings anyObjectSettings() throws IOException {
return indexManager.defaultSettings();
}
- protected XContentBuilder userMapping() throws IOException {
+ protected TypeMapping userMapping() throws IOException {
return indexManager.defaultMapping();
}
- protected XContentBuilder groupMapping() throws IOException {
+ protected TypeMapping groupMapping() throws IOException {
return indexManager.defaultMapping();
}
- protected XContentBuilder anyObjectMapping() throws IOException {
+ protected TypeMapping anyObjectMapping() throws IOException {
return indexManager.defaultMapping();
}
@@ -104,13 +105,14 @@ public class ElasticsearchReindex extends AbstractSchedTaskJobDelegate {
LOG.debug("Indexing users...");
for (int page = 1; page <= (userDAO.count() / AnyDAO.DEFAULT_PAGE_SIZE) + 1; page++) {
for (String user : userDAO.findAllKeys(page, AnyDAO.DEFAULT_PAGE_SIZE)) {
- IndexRequest request = new IndexRequest(
- ElasticsearchUtils.getContextDomainName(
+ IndexRequest<Map<String, Object>> request = new IndexRequest.Builder<Map<String, Object>>().
+ index(ElasticsearchUtils.getContextDomainName(
AuthContextUtils.getDomain(), AnyTypeKind.USER)).
id(user).
- source(utils.builder(userDAO.find(user), AuthContextUtils.getDomain()));
+ document(utils.document(userDAO.find(user), AuthContextUtils.getDomain())).
+ build();
try {
- IndexResponse response = client.index(request, RequestOptions.DEFAULT);
+ IndexResponse response = client.index(request);
LOG.debug("Index successfully created for {}: {}", user, response);
} catch (Exception e) {
LOG.error("Could not create index for {} {}", AnyTypeKind.USER, user);
@@ -121,13 +123,14 @@ public class ElasticsearchReindex extends AbstractSchedTaskJobDelegate {
LOG.debug("Indexing groups...");
for (int page = 1; page <= (groupDAO.count() / AnyDAO.DEFAULT_PAGE_SIZE) + 1; page++) {
for (String group : groupDAO.findAllKeys(page, AnyDAO.DEFAULT_PAGE_SIZE)) {
- IndexRequest request = new IndexRequest(
- ElasticsearchUtils.getContextDomainName(
+ IndexRequest<Map<String, Object>> request = new IndexRequest.Builder<Map<String, Object>>().
+ index(ElasticsearchUtils.getContextDomainName(
AuthContextUtils.getDomain(), AnyTypeKind.GROUP)).
id(group).
- source(utils.builder(groupDAO.find(group), AuthContextUtils.getDomain()));
+ document(utils.document(groupDAO.find(group), AuthContextUtils.getDomain())).
+ build();
try {
- IndexResponse response = client.index(request, RequestOptions.DEFAULT);
+ IndexResponse response = client.index(request);
LOG.debug("Index successfully created for {}: {}", group, response);
} catch (Exception e) {
LOG.error("Could not create index for {} {}", AnyTypeKind.GROUP, group);
@@ -138,13 +141,14 @@ public class ElasticsearchReindex extends AbstractSchedTaskJobDelegate {
LOG.debug("Indexing any objects...");
for (int page = 1; page <= (anyObjectDAO.count() / AnyDAO.DEFAULT_PAGE_SIZE) + 1; page++) {
for (String anyObject : anyObjectDAO.findAllKeys(page, AnyDAO.DEFAULT_PAGE_SIZE)) {
- IndexRequest request = new IndexRequest(
- ElasticsearchUtils.getContextDomainName(
+ IndexRequest<Map<String, Object>> request = new IndexRequest.Builder<Map<String, Object>>().
+ index(ElasticsearchUtils.getContextDomainName(
AuthContextUtils.getDomain(), AnyTypeKind.ANY_OBJECT)).
id(anyObject).
- source(utils.builder(anyObjectDAO.find(anyObject), AuthContextUtils.getDomain()));
+ document(utils.document(anyObjectDAO.find(anyObject), AuthContextUtils.getDomain())).
+ build();
try {
- IndexResponse response = client.index(request, RequestOptions.DEFAULT);
+ IndexResponse response = client.index(request);
LOG.debug("Index successfully created for {}: {}", anyObject, response);
} catch (Exception e) {
LOG.error("Could not create index for {} {}", AnyTypeKind.ANY_OBJECT, anyObject);
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/NotificationTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/NotificationTaskITCase.java
index 5c7b501..dde15d4 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/NotificationTaskITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/NotificationTaskITCase.java
@@ -167,12 +167,10 @@ public class NotificationTaskITCase extends AbstractNotificationTaskITCase {
taskTO = taskService.read(TaskType.NOTIFICATION, taskTO.getKey(), true);
assertNotNull(taskTO);
assertTrue(taskTO.isExecuted());
- assertEquals(1, taskTO.getExecutions().size());
+ assertFalse(taskTO.getExecutions().isEmpty());
} finally {
// Remove execution to make test re-runnable
- if (!taskTO.getExecutions().isEmpty()) {
- taskService.deleteExecution(taskTO.getExecutions().get(0).getKey());
- }
+ taskTO.getExecutions().forEach(e -> taskService.deleteExecution(e.getKey()));
}
}
diff --git a/pom.xml b/pom.xml
index 6e364c4..00acfdc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -430,7 +430,7 @@ under the License.
<slf4j.version>1.7.32</slf4j.version>
- <elasticsearch.version>7.15.2</elasticsearch.version>
+ <elasticsearch.version>7.16.2</elasticsearch.version>
<apacheds.version>2.0.0.AM26</apacheds.version>
<apachedirapi.version>2.0.0</apachedirapi.version>
@@ -677,33 +677,19 @@ under the License.
<!-- /Camel -->
<dependency>
- <groupId>org.elasticsearch.client</groupId>
- <artifactId>elasticsearch-rest-high-level-client</artifactId>
- <version>${elasticsearch.version}</version>
- <exclusions>
- <exclusion>
- <groupId>com.fasterxml.jackson.datatype</groupId>
- <artifactId>jackson-dataformat-smile</artifactId>
- </exclusion>
- <exclusion>
- <groupId>com.fasterxml.jackson.datatype</groupId>
- <artifactId>jackson-dataformat-yaml</artifactId>
- </exclusion>
- <exclusion>
- <groupId>com.fasterxml.jackson.datatype</groupId>
- <artifactId>jackson-dataformat-cbor</artifactId>
- </exclusion>
- </exclusions>
+ <groupId>co.elastic.clients</groupId>
+ <artifactId>elasticsearch-java</artifactId>
+ <version>${elasticsearch.version}</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
- <version>${elasticsearch.version}</version>
+ <version>7.16.1</version>
</dependency>
<dependency>
- <groupId>org.elasticsearch</groupId>
- <artifactId>elasticsearch</artifactId>
- <version>${elasticsearch.version}</version>
+ <groupId>jakarta.json</groupId>
+ <artifactId>jakarta.json-api</artifactId>
+ <version>2.0.1</version>
</dependency>
<dependency>