You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@unomi.apache.org by jk...@apache.org on 2022/07/21 17:02:17 UTC
[unomi] 01/01: UNOMI-605: migrate events to 2.0.0
This is an automated email from the ASF dual-hosted git repository.
jkevan pushed a commit to branch migrateEvents
in repository https://gitbox.apache.org/repos/asf/unomi.git
commit bc3abcd32df1ff6e899895f7604bfa5cb9d0a6db
Author: Kevan <ke...@jahia.com>
AuthorDate: Thu Jul 21 19:01:59 2022 +0200
UNOMI-605: migrate events to 2.0.0
---
.../unomi/shell/migration/impl/MigrationTo200.java | 64 +---------------
.../shell/migration/utils/MigrationUtils.java | 19 +++++
.../migrate-2.0.0-03-profileReindex.groovy | 2 +-
.../migrate-2.0.0-04-eventsReindex.groovy | 34 +++++++++
.../requestBody/2.0.0/event_delete_by_query.json | 15 ++++
.../resources/requestBody/2.0.0/event_index.json | 87 ++++++++++++++++++++++
.../requestBody/2.0.0/event_migrate.painless | 55 ++++++++++++++
...interests.painless => profile_migrate.painless} | 0
8 files changed, 212 insertions(+), 64 deletions(-)
diff --git a/tools/shell-commands/src/main/java/org/apache/unomi/shell/migration/impl/MigrationTo200.java b/tools/shell-commands/src/main/java/org/apache/unomi/shell/migration/impl/MigrationTo200.java
index edd92562e..3e8967ed0 100644
--- a/tools/shell-commands/src/main/java/org/apache/unomi/shell/migration/impl/MigrationTo200.java
+++ b/tools/shell-commands/src/main/java/org/apache/unomi/shell/migration/impl/MigrationTo200.java
@@ -61,74 +61,12 @@ public class MigrationTo200 implements Migration {
}
private void doExecute(String indexPrefix) throws IOException {
- Set<String> indexes = getEventIndexes(indexPrefix);
- for (String index : indexes) {
- updateMapping(index);
- }
+ Set<String> indexes = MigrationUtils.getIndexesPrefixedBy(httpClient, esAddress, indexPrefix + "-event-");
createScopeMapping(indexPrefix);
createScopes(getSetOfScopes(indexes), indexPrefix);
createProfileAliasDocumentsFromProfile();
}
- private void updateMapping(final String indexName) throws IOException {
- HttpPut httpPut = new HttpPut(esAddress + "/" + indexName + "/_mapping");
-
- httpPut.addHeader("Accept", "application/json");
- httpPut.addHeader("Content-Type", "application/json");
-
- String requestBody = MigrationUtils.resourceAsString(bundleContext,"requestBody/updateMapping.json");
-
- httpPut.setEntity(new StringEntity(requestBody));
-
- try (CloseableHttpResponse response = httpClient.execute(httpPut)) {
- JSONObject responseAsJson = new JSONObject(EntityUtils.toString(response.getEntity()));
-
- if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK && responseAsJson.has("acknowledged") && responseAsJson
- .getBoolean("acknowledged")) {
- System.out.println("Mapping for index = \"" + indexName + "\" successfully updated.");
-
- copyValueScopeToSourceId(indexName, httpClient);
- } else {
- System.out.println("Update the mapping for index = \"" + indexName + "\" failed.");
- }
- }
- }
-
- private void copyValueScopeToSourceId(final String indexName, final CloseableHttpClient httpClient) throws IOException {
- final HttpPost httpPost = new HttpPost(esAddress + "/" + indexName + "/_update_by_query");
-
- httpPost.addHeader("Accept", "application/json");
- httpPost.addHeader("Content-Type", "application/json");
-
- String requestBody = MigrationUtils.resourceAsString(bundleContext,"requestBody/copyValueScopeToSourceId.json");
-
- httpPost.setEntity(new StringEntity(requestBody));
-
- try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
- JSONObject responseAsJson = new JSONObject(EntityUtils.toString(response.getEntity()));
-
- if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
- System.out.println("Copying the \"scope\" field to the \"sourceId\" field for index = \"" + indexName
- + "\" successfully completed. Total: " + responseAsJson.get("total") + ", updated: " + responseAsJson.get("updated")
- + ".");
- } else {
- System.out.println("Copying the \"scope\" field to the \"sourceId\" field for index = \"" + indexName + "\" failed.");
- }
- }
- }
-
- private Set<String> getEventIndexes(String indexPrefix) throws IOException {
- try (CloseableHttpResponse response = httpClient.execute(new HttpGet(esAddress + "/_aliases"))) {
- if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
- JSONObject indexesAsJson = new JSONObject(EntityUtils.toString(response.getEntity()));
- return indexesAsJson.keySet().stream().
- filter(alias -> alias.startsWith(indexPrefix + "-event")).
- collect(Collectors.toSet());
- }
- }
- return Collections.emptySet();
- }
-
private boolean scopeIndexNotExists(String indexPrefix) throws IOException {
final HttpGet httpGet = new HttpGet(esAddress + "/" + indexPrefix + "-scope");
diff --git a/tools/shell-commands/src/main/java/org/apache/unomi/shell/migration/utils/MigrationUtils.java b/tools/shell-commands/src/main/java/org/apache/unomi/shell/migration/utils/MigrationUtils.java
index f055be2d3..33b0278ed 100644
--- a/tools/shell-commands/src/main/java/org/apache/unomi/shell/migration/utils/MigrationUtils.java
+++ b/tools/shell-commands/src/main/java/org/apache/unomi/shell/migration/utils/MigrationUtils.java
@@ -18,7 +18,11 @@ package org.apache.unomi.shell.migration.utils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.util.EntityUtils;
import org.json.JSONObject;
import org.osgi.framework.BundleContext;
@@ -29,6 +33,9 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.Set;
+import java.util.stream.Collectors;
/**
* @author dgaillard
@@ -78,6 +85,18 @@ public class MigrationUtils {
}
}
+ public static Set<String> getIndexesPrefixedBy(CloseableHttpClient httpClient, String esAddress, String prefix) throws IOException {
+ try (CloseableHttpResponse response = httpClient.execute(new HttpGet(esAddress + "/_aliases"))) {
+ if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
+ JSONObject indexesAsJson = new JSONObject(EntityUtils.toString(response.getEntity()));
+ return indexesAsJson.keySet().stream().
+ filter(alias -> alias.startsWith(prefix)).
+ collect(Collectors.toSet());
+ }
+ }
+ return Collections.emptySet();
+ }
+
public static void reIndex(CloseableHttpClient httpClient, BundleContext bundleContext, String esAddress, String indexName,
String newIndexSettings, String painlessScript) throws IOException {
String indexNameCloned = indexName + "-cloned";
diff --git a/tools/shell-commands/src/main/resources/META-INF/cxs/migration/migrate-2.0.0-03-profileReindex.groovy b/tools/shell-commands/src/main/resources/META-INF/cxs/migration/migrate-2.0.0-03-profileReindex.groovy
index 5eaa63e0e..83ab51233 100644
--- a/tools/shell-commands/src/main/resources/META-INF/cxs/migration/migrate-2.0.0-03-profileReindex.groovy
+++ b/tools/shell-commands/src/main/resources/META-INF/cxs/migration/migrate-2.0.0-03-profileReindex.groovy
@@ -19,4 +19,4 @@ import org.apache.unomi.shell.migration.utils.MigrationUtils
String newIndexSettings = MigrationUtils.resourceAsString(bundleContext, "requestBody/2.0.0/profile_index.json");
MigrationUtils.reIndex(httpClient, bundleContext, migrationConfig.get("esAddress"), migrationConfig.get("indexPrefix") + "-profile",
- newIndexSettings, MigrationUtils.getFileWithoutComments(bundleContext, "requestBody/2.0.0/migrate_existing_interests.painless"))
+ newIndexSettings, MigrationUtils.getFileWithoutComments(bundleContext, "requestBody/2.0.0/profile_migrate.painless"))
diff --git a/tools/shell-commands/src/main/resources/META-INF/cxs/migration/migrate-2.0.0-04-eventsReindex.groovy b/tools/shell-commands/src/main/resources/META-INF/cxs/migration/migrate-2.0.0-04-eventsReindex.groovy
new file mode 100644
index 000000000..10c64646f
--- /dev/null
+++ b/tools/shell-commands/src/main/resources/META-INF/cxs/migration/migrate-2.0.0-04-eventsReindex.groovy
@@ -0,0 +1,34 @@
+import org.apache.unomi.shell.migration.utils.HttpUtils
+import org.apache.unomi.shell.migration.utils.MigrationUtils
+
+/*
+ * 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.
+ */
+
+String esAddress = migrationConfig.get("esAddress")
+String indexPrefix = migrationConfig.get("indexPrefix")
+
+// Remove all internal events that are no more persisted
+String removeInternalEventsRequest = MigrationUtils.resourceAsString(bundleContext, "requestBody/2.0.0/event_delete_by_query.json")
+HttpUtils.executePostRequest(httpClient, "${esAddress}/${indexPrefix}-event-*/_delete_by_query", removeInternalEventsRequest, null)
+
+// Reindex the rest of the events
+String newIndexSettings = MigrationUtils.resourceAsString(bundleContext, "requestBody/2.0.0/event_index.json");
+String reIndexScript = MigrationUtils.getFileWithoutComments(bundleContext, "requestBody/2.0.0/event_migrate.painless");
+Set<String> eventIndices = MigrationUtils.getIndexesPrefixedBy(httpClient, esAddress, "${indexPrefix}-event-")
+eventIndices.each { eventIndex ->
+ MigrationUtils.reIndex(httpClient, bundleContext, esAddress, eventIndex, newIndexSettings, reIndexScript)
+}
\ No newline at end of file
diff --git a/tools/shell-commands/src/main/resources/requestBody/2.0.0/event_delete_by_query.json b/tools/shell-commands/src/main/resources/requestBody/2.0.0/event_delete_by_query.json
new file mode 100644
index 000000000..7830da7f5
--- /dev/null
+++ b/tools/shell-commands/src/main/resources/requestBody/2.0.0/event_delete_by_query.json
@@ -0,0 +1,15 @@
+{
+ "query": {
+ "bool": {
+ "should": [
+ {"term": {"eventType.keyword": "profileUpdated"}},
+ {"term": {"eventType.keyword": "profileDeleted"}},
+ {"term": {"eventType.keyword": "anonymizeProfile"}},
+ {"term": {"eventType.keyword": "sessionCreated"}},
+ {"term": {"eventType.keyword": "sessionReassigned"}},
+ {"term": {"eventType.keyword": "updateProperties"}},
+ {"term": {"eventType.keyword": "goal"}}
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/tools/shell-commands/src/main/resources/requestBody/2.0.0/event_index.json b/tools/shell-commands/src/main/resources/requestBody/2.0.0/event_index.json
new file mode 100644
index 000000000..a0e25f945
--- /dev/null
+++ b/tools/shell-commands/src/main/resources/requestBody/2.0.0/event_index.json
@@ -0,0 +1,87 @@
+{
+ "settings": {
+ "index": {
+ "number_of_shards": #numberOfShards,
+ "number_of_replicas": #numberOfReplicas,
+ "mapping.total_fields.limit": #mappingTotalFieldsLimit,
+ "max_docvalue_fields_search": #maxDocValueFieldsSearch
+ },
+ "analysis": {
+ "analyzer": {
+ "folding": {
+ "type": "custom",
+ "tokenizer": "keyword",
+ "filter": [
+ "lowercase",
+ "asciifolding"
+ ]
+ }
+ }
+ }
+ },
+ "mappings": {
+ "dynamic_templates": [
+ {
+ "all": {
+ "match": "*",
+ "match_mapping_type": "string",
+ "mapping": {
+ "type": "text",
+ "analyzer": "folding",
+ "fields": {
+ "keyword": {
+ "type": "keyword",
+ "ignore_above": 256
+ }
+ }
+ }
+ }
+ }
+ ],
+ "properties": {
+ "flattenedProperties": {
+ "type": "flattened"
+ },
+ "timeStamp": {
+ "type": "date"
+ },
+ "target" : {
+ "properties" : {
+ "lastEventDate" : {
+ "type" : "date"
+ },
+ "profile" : {
+ "properties" : {
+ "properties" : {
+ "properties" : {
+ "birthDate" : {
+ "type" : "date"
+ },
+ "firstVisit" : {
+ "type" : "date"
+ },
+ "lastVisit" : {
+ "type" : "date"
+ },
+ "notificationRefreshDate" : {
+ "type" : "date"
+ },
+ "previousVisit" : {
+ "type" : "date"
+ }
+ }
+ },
+ "systemProperties" : {
+ "properties" : {
+
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+}
diff --git a/tools/shell-commands/src/main/resources/requestBody/2.0.0/event_migrate.painless b/tools/shell-commands/src/main/resources/requestBody/2.0.0/event_migrate.painless
new file mode 100644
index 000000000..4fd878064
--- /dev/null
+++ b/tools/shell-commands/src/main/resources/requestBody/2.0.0/event_migrate.painless
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+/* Handle view events */
+if ('view' == ctx._source.eventType){
+
+ /* Check for interests */
+ if (ctx._source.target != null && ctx._source.target.properties != null && ctx._source.target.properties.interests != null){
+
+ if (ctx._source.flattenedProperties == null) {
+ ctx._source.put('flattenedProperties', new HashMap());
+ }
+ ctx._source.flattenedProperties.put('interests', ctx._source.target.properties.interests);
+ ctx._source.target.properties.remove('interests');
+ }
+
+ /* Check for URL parameters */
+ if (ctx._source.target != null && ctx._source.target.properties != null && ctx._source.target.properties.pageInfo != null &&
+ ctx._source.target.properties.pageInfo.parameters != null){
+
+ if (ctx._source.flattenedProperties == null) {
+ ctx._source.put('flattenedProperties', new HashMap());
+ }
+ ctx._source.flattenedProperties.put('URLParameters', ctx._source.target.properties.pageInfo.parameters);
+ ctx._source.target.properties.pageInfo.remove('parameters');
+ }
+}
+
+/* Handle form events */
+if ('form' == ctx._source.eventType){
+
+ /* Check for form fields */
+ if (ctx._source.properties != null){
+
+ if (ctx._source.flattenedProperties == null) {
+ ctx._source.put('flattenedProperties', new HashMap());
+ }
+ ctx._source.flattenedProperties.put('fields', ctx._source.properties);
+ ctx._source.put('properties', new HashMap());
+ }
+}
\ No newline at end of file
diff --git a/tools/shell-commands/src/main/resources/requestBody/2.0.0/migrate_existing_interests.painless b/tools/shell-commands/src/main/resources/requestBody/2.0.0/profile_migrate.painless
similarity index 100%
rename from tools/shell-commands/src/main/resources/requestBody/2.0.0/migrate_existing_interests.painless
rename to tools/shell-commands/src/main/resources/requestBody/2.0.0/profile_migrate.painless