From eb83fa04761a02324798e9d0f4ee948834662aee Mon Sep 17 00:00:00 2001 From: Chris Helma <25470211+chelma@users.noreply.github.com> Date: Wed, 25 Sep 2024 16:25:05 -0500 Subject: [PATCH] Updated the ES 7.X transformation code to handle arbitrary type names (#1014) * Updated the ES 7.X transformation code to handle arbitrary type names Signed-off-by: Chris Helma * Minor tweaks to transformer code Signed-off-by: Chris Helma * Improved a comment Signed-off-by: Chris Helma * Made Spotless happy Signed-off-by: Chris Helma * Updates per PR comments and discussion Signed-off-by: Chris Helma --------- Signed-off-by: Chris Helma --- .../docker/docker-compose-es710.yml | 8 +- .../transformers/TransformFunctions.java | 67 ++++++++--- .../bulkload/common/TestResources.java | 6 + .../Transformer_ES_7_10_OS_2_11Test.java | 68 ++++++++++++ RFS/test-resources/inventory.md | 104 ++++++++++++++++++ .../snapshots/ES_7_10_BWC_Check/index-0 | 1 + .../snapshots/ES_7_10_BWC_Check/index.latest | Bin 0 -> 8 bytes .../0/__7d8i9c5gTH62_a-mtjnh1g | Bin 0 -> 479 bytes .../0/__xdhJGeuxSAGPk5gBj8PlfA | Bin 0 -> 2742 bytes .../0/index-73ZKrS4iTc6nKzY0E4kC1w | Bin 0 -> 1245 bytes .../0/snap-rNzQqxl5Qrm99ZzB44Yz0w.dat | Bin 0 -> 1154 bytes .../meta-AzJBKpIBKBXpMe1tfd-g.dat | Bin 0 -> 525 bytes .../0/__d3rngFHgRnOiALrbvS6Odg | Bin 0 -> 479 bytes .../0/__q7cUOllVStaQMJVUtgWEPQ | Bin 0 -> 2740 bytes .../0/index-OSYnb8w3SKmTqQ_p7m84JA | Bin 0 -> 1245 bytes .../0/snap-rNzQqxl5Qrm99ZzB44Yz0w.dat | Bin 0 -> 1154 bytes .../meta-AjJBKpIBKBXpMe1tfd-g.dat | Bin 0 -> 535 bytes .../meta-rNzQqxl5Qrm99ZzB44Yz0w.dat | Bin 0 -> 717 bytes .../snap-rNzQqxl5Qrm99ZzB44Yz0w.dat | Bin 0 -> 287 bytes 19 files changed, 230 insertions(+), 24 deletions(-) create mode 100644 RFS/src/test/java/org/opensearch/migrations/bulkload/transformers/Transformer_ES_7_10_OS_2_11Test.java create mode 100644 RFS/test-resources/snapshots/ES_7_10_BWC_Check/index-0 create mode 100644 RFS/test-resources/snapshots/ES_7_10_BWC_Check/index.latest create mode 100644 RFS/test-resources/snapshots/ES_7_10_BWC_Check/indices/6f5_qLyfQu-MKqe5IEJGuQ/0/__7d8i9c5gTH62_a-mtjnh1g create mode 100644 RFS/test-resources/snapshots/ES_7_10_BWC_Check/indices/6f5_qLyfQu-MKqe5IEJGuQ/0/__xdhJGeuxSAGPk5gBj8PlfA create mode 100644 RFS/test-resources/snapshots/ES_7_10_BWC_Check/indices/6f5_qLyfQu-MKqe5IEJGuQ/0/index-73ZKrS4iTc6nKzY0E4kC1w create mode 100644 RFS/test-resources/snapshots/ES_7_10_BWC_Check/indices/6f5_qLyfQu-MKqe5IEJGuQ/0/snap-rNzQqxl5Qrm99ZzB44Yz0w.dat create mode 100644 RFS/test-resources/snapshots/ES_7_10_BWC_Check/indices/6f5_qLyfQu-MKqe5IEJGuQ/meta-AzJBKpIBKBXpMe1tfd-g.dat create mode 100644 RFS/test-resources/snapshots/ES_7_10_BWC_Check/indices/rtO3hIcQREynKwRVke75sQ/0/__d3rngFHgRnOiALrbvS6Odg create mode 100644 RFS/test-resources/snapshots/ES_7_10_BWC_Check/indices/rtO3hIcQREynKwRVke75sQ/0/__q7cUOllVStaQMJVUtgWEPQ create mode 100644 RFS/test-resources/snapshots/ES_7_10_BWC_Check/indices/rtO3hIcQREynKwRVke75sQ/0/index-OSYnb8w3SKmTqQ_p7m84JA create mode 100644 RFS/test-resources/snapshots/ES_7_10_BWC_Check/indices/rtO3hIcQREynKwRVke75sQ/0/snap-rNzQqxl5Qrm99ZzB44Yz0w.dat create mode 100644 RFS/test-resources/snapshots/ES_7_10_BWC_Check/indices/rtO3hIcQREynKwRVke75sQ/meta-AjJBKpIBKBXpMe1tfd-g.dat create mode 100644 RFS/test-resources/snapshots/ES_7_10_BWC_Check/meta-rNzQqxl5Qrm99ZzB44Yz0w.dat create mode 100644 RFS/test-resources/snapshots/ES_7_10_BWC_Check/snap-rNzQqxl5Qrm99ZzB44Yz0w.dat diff --git a/DocumentsFromSnapshotMigration/docker/docker-compose-es710.yml b/DocumentsFromSnapshotMigration/docker/docker-compose-es710.yml index 500d1b026..45ecef415 100644 --- a/DocumentsFromSnapshotMigration/docker/docker-compose-es710.yml +++ b/DocumentsFromSnapshotMigration/docker/docker-compose-es710.yml @@ -14,7 +14,7 @@ services: ports: - '19200:9200' volumes: - - snapshotStorage:/snapshots + - ./snapshots:/snapshots # Sample command to kick off RFS here: https://github.com/opensearch-project/opensearch-migrations/blob/main/RFS/README.md#using-docker reindex-from-snapshot: @@ -31,7 +31,7 @@ services: - AWS_SECRET_ACCESS_KEY=${secret_key} - AWS_SESSION_TOKEN=${session_token} volumes: - - snapshotStorage:/snapshots + - ./snapshots:/snapshots opensearchtarget: image: 'opensearchproject/opensearch:2.11.1' @@ -46,7 +46,3 @@ services: networks: migrations: driver: bridge - -volumes: - snapshotStorage: - driver: local diff --git a/RFS/src/main/java/org/opensearch/migrations/bulkload/transformers/TransformFunctions.java b/RFS/src/main/java/org/opensearch/migrations/bulkload/transformers/TransformFunctions.java index c8a19369a..80a5e7004 100644 --- a/RFS/src/main/java/org/opensearch/migrations/bulkload/transformers/TransformFunctions.java +++ b/RFS/src/main/java/org/opensearch/migrations/bulkload/transformers/TransformFunctions.java @@ -60,35 +60,66 @@ public static ObjectNode convertFlatSettingsToTree(ObjectNode flatSettings) { } /** - * If the object has mappings, then we need to ensure they aren't burried underneath an intermediate levels. - * This can show up a number of ways: - * - [{"_doc":{"properties":{"address":{"type":"text"}}}}] - * - [{"doc":{"properties":{"address":{"type":"text"}}}}] - * - [{"audit_message":{"properties":{"address":{"type":"text"}}}}] + * If the object has mappings, then we need to ensure they aren't burried underneath intermediate levels. */ public static void removeIntermediateMappingsLevels(ObjectNode root) { if (root.has(MAPPINGS_KEY_STR)) { var val = root.get(MAPPINGS_KEY_STR); + /** + * This probably came from a Snapshot + * There should only be a single member in the list because multi-type mappings were deprecated in ES 6.X and + * removed in ES 7.X. This list structure appears to be a holdover from previous versions of Elasticsearch. + * The exact name of the type can be arbitrarily chosen by the user; the default is _doc. We need to extract + * the mappings from beneath this intermediate key regardless of what it is named. + * - [{"_doc":{"properties":{"address":{"type":"text"}}}}] + * - [{"doc":{"properties":{"address":{"type":"text"}}}}] + * - [{"audit_message":{"properties":{"address":{"type":"text"}}}}] + * + * It's not impossible that the intermediate key is not present, in which case we should just extract the mappings: + * - [{"properties":{"address":{"type":"text"}}}] + */ if (val instanceof ArrayNode) { ArrayNode mappingsList = (ArrayNode) val; - root.set(MAPPINGS_KEY_STR, getMappingsFromBeneathIntermediate(mappingsList)); + if (mappingsList.size() != 1) { + throw new IllegalArgumentException("Mappings list contains more than one member; this is unexpected: " + val.toString()); + } + ObjectNode actualMappingsRoot = (ObjectNode) mappingsList.get(0); + + root.set(MAPPINGS_KEY_STR, getMappingsFromBeneathIntermediate(actualMappingsRoot)); + } + + /** + * This came from somewhere else (like a REST call to the source cluster). It should be in a shape like: + * - {"_doc":{"properties":{"address":{"type":"text"}}}} + * - {"properties":{"address":{"type":"text"}}} + */ + else if (val instanceof ObjectNode) { + root.set(MAPPINGS_KEY_STR, getMappingsFromBeneathIntermediate((ObjectNode) val)); + } + + else { + throw new IllegalArgumentException("Mappings object is not in the expected shape: " + val.toString()); } } } - // Extract the mappings from their single-member list, will start like: - // [{"_doc":{"properties":{"address":{"type":"text"}}}}] - public static ObjectNode getMappingsFromBeneathIntermediate(ArrayNode mappingsRoot) { - ObjectNode actualMappingsRoot = (ObjectNode) mappingsRoot.get(0); - if (actualMappingsRoot.has("_doc")) { - return (ObjectNode) actualMappingsRoot.get("_doc").deepCopy(); - } else if (actualMappingsRoot.has("doc")) { - return (ObjectNode) actualMappingsRoot.get("doc").deepCopy(); - } else if (actualMappingsRoot.has("audit_message")) { - return (ObjectNode) actualMappingsRoot.get("audit_message").deepCopy(); - } else { - throw new IllegalArgumentException("Mappings root does not contain one of the expected keys"); + /** + * Extract the mappings from the type dict. It may be that there is no intermediate type key as well. So, the + * input could be: + * {"_doc":{"properties":{"address":{"type":"text"}}}} + * {"properties":{"address":{"type":"text"}}} + * + * If there is a type key ('_doc', etc), the key name can be arbitrary. We need to extract the mappings from beneath + * it regardless of what it is named. + */ + public static ObjectNode getMappingsFromBeneathIntermediate(ObjectNode mappingsRoot) { + if (mappingsRoot.has("properties")) { + return mappingsRoot; + } else if (!mappingsRoot.has("properties")) { + return (ObjectNode) mappingsRoot.get(mappingsRoot.fieldNames().next()).deepCopy(); } + + throw new IllegalArgumentException("Mappings object is not in the expected shape: " + mappingsRoot.toString()); } /** diff --git a/RFS/src/test/java/org/opensearch/migrations/bulkload/common/TestResources.java b/RFS/src/test/java/org/opensearch/migrations/bulkload/common/TestResources.java index ec3973dc2..7714beeb5 100644 --- a/RFS/src/test/java/org/opensearch/migrations/bulkload/common/TestResources.java +++ b/RFS/src/test/java/org/opensearch/migrations/bulkload/common/TestResources.java @@ -15,6 +15,7 @@ public static class Snapshot { public static final Snapshot SNAPSHOT_ES_5_6; public static final Snapshot SNAPSHOT_ES_6_8; public static final Snapshot SNAPSHOT_ES_6_8_MERGED; + public static final Snapshot SNAPSHOT_ES_7_10_BWC_CHECK; public static final Snapshot SNAPSHOT_ES_7_10_W_SOFT; public static final Snapshot SNAPSHOT_ES_7_10_WO_SOFT; @@ -36,6 +37,11 @@ public static class Snapshot { "rfs_snapshot" ); + SNAPSHOT_ES_7_10_BWC_CHECK = new Snapshot( + rfsBaseDir.resolve(Paths.get("test-resources", "snapshots", "ES_7_10_BWC_Check")), + "rfs-snapshot" + ); + SNAPSHOT_ES_7_10_W_SOFT = new Snapshot( rfsBaseDir.resolve(Paths.get("test-resources", "snapshots", "ES_7_10_Updates_Deletes_w_Soft")), "rfs_snapshot" diff --git a/RFS/src/test/java/org/opensearch/migrations/bulkload/transformers/Transformer_ES_7_10_OS_2_11Test.java b/RFS/src/test/java/org/opensearch/migrations/bulkload/transformers/Transformer_ES_7_10_OS_2_11Test.java new file mode 100644 index 000000000..bed907250 --- /dev/null +++ b/RFS/src/test/java/org/opensearch/migrations/bulkload/transformers/Transformer_ES_7_10_OS_2_11Test.java @@ -0,0 +1,68 @@ +package org.opensearch.migrations.bulkload.transformers; + + +import org.junit.jupiter.api.Test; + +import org.opensearch.migrations.Version; +import org.opensearch.migrations.bulkload.common.FileSystemRepo; +import org.opensearch.migrations.bulkload.common.TestResources; +import org.opensearch.migrations.bulkload.models.GlobalMetadata; +import org.opensearch.migrations.bulkload.models.IndexMetadata; +import org.opensearch.migrations.bulkload.version_os_2_11.GlobalMetadataData_OS_2_11; +import org.opensearch.migrations.bulkload.version_os_2_11.IndexMetadataData_OS_2_11; +import org.opensearch.migrations.cluster.ClusterProviderRegistry; + +import lombok.extern.slf4j.Slf4j; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@Slf4j +public class Transformer_ES_7_10_OS_2_11Test { + @Test + public void transformGlobalMetadata_AsExpected() throws Exception { + TestResources.Snapshot snapshot = TestResources.SNAPSHOT_ES_7_10_BWC_CHECK; + Version version = Version.fromString("ES 7.10"); + + final var repo = new FileSystemRepo(snapshot.dir); + var sourceResourceProvider = ClusterProviderRegistry.getSnapshotReader(version, repo); + + Transformer_ES_7_10_OS_2_11 transformer = new Transformer_ES_7_10_OS_2_11(2); + + GlobalMetadata globalMetadata = sourceResourceProvider.getGlobalMetadata().fromRepo(snapshot.name); + GlobalMetadata transformedGlobalMetadata = transformer.transformGlobalMetadata(globalMetadata); + GlobalMetadataData_OS_2_11 finalMetadata = new GlobalMetadataData_OS_2_11(transformedGlobalMetadata.toObjectNode()); + + String expectedBwcTemplates = "{\"bwc_template\":{\"order\":0,\"index_patterns\":[\"bwc_index*\"],\"settings\":{\"number_of_shards\":\"1\",\"number_of_replicas\":\"0\"},\"mappings\":[{\"arbitrary_type\":{\"properties\":{\"title\":{\"type\":\"text\"},\"content\":{\"type\":\"text\"}}}}],\"aliases\":{\"bwc_alias\":{}}}}"; + String expectedIndexTemplates = "{\"fwc_template\":{\"index_patterns\":[\"fwc_index*\"],\"template\":{\"aliases\":{\"fwc_alias\":{}}},\"composed_of\":[\"fwc_mappings\",\"fwc_settings\"]}}"; + String expectedComponentTemplates = "{\"fwc_settings\":{\"template\":{\"settings\":{\"index\":{\"number_of_shards\":\"1\",\"number_of_replicas\":\"0\"}}}},\"fwc_mappings\":{\"template\":{\"mappings\":{\"properties\":{\"title\":{\"type\":\"text\"},\"content\":{\"type\":\"text\"}}}}}}"; + + assertEquals(expectedBwcTemplates, finalMetadata.getTemplates().toString()); + assertEquals(expectedIndexTemplates, finalMetadata.getIndexTemplates().toString()); + assertEquals(expectedComponentTemplates, finalMetadata.getComponentTemplates().toString()); + } + + @Test + public void transformIndexMetadata_AsExpected() throws Exception { + TestResources.Snapshot snapshot = TestResources.SNAPSHOT_ES_7_10_BWC_CHECK; + Version version = Version.fromString("ES 7.10"); + + final var repo = new FileSystemRepo(snapshot.dir); + var sourceResourceProvider = ClusterProviderRegistry.getSnapshotReader(version, repo); + + Transformer_ES_7_10_OS_2_11 transformer = new Transformer_ES_7_10_OS_2_11(2); + + IndexMetadata indexMetadataBwc = sourceResourceProvider.getIndexMetadata().fromRepo(snapshot.name, "bwc_index_1"); + IndexMetadata transformedIndexBwc = transformer.transformIndexMetadata(indexMetadataBwc); + IndexMetadataData_OS_2_11 finalIndexBwc =new IndexMetadataData_OS_2_11(transformedIndexBwc.getRawJson(), transformedIndexBwc.getId(), transformedIndexBwc.getName()); + + IndexMetadata indexMetadataFwc = sourceResourceProvider.getIndexMetadata().fromRepo(snapshot.name, "fwc_index_1"); + IndexMetadata transformedIndexFwc = transformer.transformIndexMetadata(indexMetadataFwc); + IndexMetadataData_OS_2_11 finalIndexFwc =new IndexMetadataData_OS_2_11(transformedIndexFwc.getRawJson(), transformedIndexFwc.getId(), transformedIndexFwc.getName()); + + String expectedIndexBwc = "{\"version\":3,\"mapping_version\":1,\"settings_version\":1,\"aliases_version\":1,\"routing_num_shards\":1024,\"state\":\"open\",\"settings\":{\"creation_date\":\"1727285787498\",\"number_of_replicas\":1,\"number_of_shards\":\"1\",\"provided_name\":\"bwc_index_1\",\"uuid\":\"P4PDS4fFSECIprHxpKSoiQ\",\"version\":{\"created\":\"7100299\"}},\"mappings\":{\"properties\":{\"content\":{\"type\":\"text\"},\"title\":{\"type\":\"text\"}}},\"aliases\":{\"bwc_alias\":{}},\"primary_terms\":[1],\"in_sync_allocations\":{\"0\":[\"0M-gMXkNQFC02lnWJN4BVQ\"]},\"rollover_info\":{},\"system\":false}"; + String expectedIndexFwc = "{\"version\":3,\"mapping_version\":1,\"settings_version\":1,\"aliases_version\":1,\"routing_num_shards\":1024,\"state\":\"open\",\"settings\":{\"creation_date\":\"1727285787822\",\"number_of_replicas\":1,\"number_of_shards\":\"1\",\"provided_name\":\"fwc_index_1\",\"uuid\":\"riC1gLlrR2eh_uAh9Zdpiw\",\"version\":{\"created\":\"7100299\"}},\"mappings\":{\"properties\":{\"content\":{\"type\":\"text\"},\"title\":{\"type\":\"text\"}}},\"aliases\":{\"fwc_alias\":{}},\"primary_terms\":[1],\"in_sync_allocations\":{\"0\":[\"8sKrVCEaSxy4yP3cx8kcYQ\"]},\"rollover_info\":{},\"system\":false}"; + + assertEquals(expectedIndexBwc, finalIndexBwc.getRawJson().toString()); + assertEquals(expectedIndexFwc, finalIndexFwc.getRawJson().toString()); + } +} diff --git a/RFS/test-resources/inventory.md b/RFS/test-resources/inventory.md index bf39ae6e3..e690b5f76 100644 --- a/RFS/test-resources/inventory.md +++ b/RFS/test-resources/inventory.md @@ -342,4 +342,108 @@ curl -X PUT "localhost:19200/test_updates_deletes" -H "Content-Type: application } } }' +``` + +#### ES_7_10_BWC_Check +An Elastic 7.10 snapshot repo designed to exercise backwards compatibility across a couple different features. It contains two indices; one is created using pre-ES 7.8 templates and pre-ES 7.0 type declarations, and the other is created using forward-compatible index/component templates and no type declarations. Both indices contain a single document. + +``` +curl -X PUT "localhost:19200/_template/bwc_template?include_type_name=true" -H "Content-Type: application/json" -d ' +{ + "index_patterns": ["bwc_index*"], + "settings": { + "index": { + "number_of_shards": 1, + "number_of_replicas": 0 + } + }, + "mappings": { + "arbitrary_type": { + "properties": { + "title": { + "type": "text" + }, + "content": { + "type": "text" + } + } + } + }, + "aliases": { + "bwc_alias": {} + } +}' + +curl -X PUT "localhost:19200/bwc_index_1" -H "Content-Type: application/json" + +curl -X PUT "localhost:19200/bwc_alias/_doc/bwc_doc" -H "Content-Type: application/json" -d ' +{ + "title": "This is a doc in a backwards compatible index", + "content": "Four score and seven years ago" +}' + +curl -X PUT "localhost:19200/_component_template/fwc_mappings" -H "Content-Type: application/json" -d ' +{ + "template": { + "mappings": { + "properties": { + "title": { + "type": "text" + }, + "content": { + "type": "text" + } + } + } + } +}' + +curl -X PUT "localhost:19200/_component_template/fwc_settings" -H "Content-Type: application/json" -d ' +{ + "template": { + "settings": { + "index": { + "number_of_shards": 1, + "number_of_replicas": 0 + } + } + } +}' + +curl -X PUT "localhost:19200/_index_template/fwc_template" -H "Content-Type: application/json" -d ' +{ + "index_patterns": ["fwc_index*"], + "composed_of": [ + "fwc_mappings", + "fwc_settings" + ], + "template": { + "aliases": { + "fwc_alias": {} + } + } +}' + +curl -X PUT "localhost:19200/fwc_index_1" -H "Content-Type: application/json" + +curl -X PUT "localhost:19200/fwc_alias/_doc/bwc_doc" -H "Content-Type: application/json" -d ' +{ + "title": "This is a doc in a forward compatible index", + "content": "Life, the Universe, and Everything" +}' + +curl -X PUT "localhost:19200/_snapshot/test_repository" -H "Content-Type: application/json" -d '{ + "type": "fs", + "settings": { + "location": "/snapshots", + "compress": false + } +}' + +curl -X PUT "localhost:19200/_snapshot/test_repository/rfs-snapshot" -H "Content-Type: application/json" -d '{ + "indices": "bwc_index_1,fwc_index_1", + "ignore_unavailable": true, + "include_global_state": true +}' + ``` \ No newline at end of file diff --git a/RFS/test-resources/snapshots/ES_7_10_BWC_Check/index-0 b/RFS/test-resources/snapshots/ES_7_10_BWC_Check/index-0 new file mode 100644 index 000000000..5d1e24f27 --- /dev/null +++ b/RFS/test-resources/snapshots/ES_7_10_BWC_Check/index-0 @@ -0,0 +1 @@ +{"snapshots":[{"name":"rfs-snapshot","uuid":"rNzQqxl5Qrm99ZzB44Yz0w","state":1,"index_metadata_lookup":{"rtO3hIcQREynKwRVke75sQ":"P4PDS4fFSECIprHxpKSoiQ-_na_-1-1-1","6f5_qLyfQu-MKqe5IEJGuQ":"riC1gLlrR2eh_uAh9Zdpiw-_na_-1-1-1"},"version":"7.10.2"}],"indices":{"bwc_index_1":{"id":"rtO3hIcQREynKwRVke75sQ","snapshots":["rNzQqxl5Qrm99ZzB44Yz0w"],"shard_generations":["OSYnb8w3SKmTqQ_p7m84JA"]},"fwc_index_1":{"id":"6f5_qLyfQu-MKqe5IEJGuQ","snapshots":["rNzQqxl5Qrm99ZzB44Yz0w"],"shard_generations":["73ZKrS4iTc6nKzY0E4kC1w"]}},"min_version":"7.9.0","index_metadata_identifiers":{"riC1gLlrR2eh_uAh9Zdpiw-_na_-1-1-1":"AzJBKpIBKBXpMe1tfd-g","P4PDS4fFSECIprHxpKSoiQ-_na_-1-1-1":"AjJBKpIBKBXpMe1tfd-g"}} \ No newline at end of file diff --git a/RFS/test-resources/snapshots/ES_7_10_BWC_Check/index.latest b/RFS/test-resources/snapshots/ES_7_10_BWC_Check/index.latest new file mode 100644 index 0000000000000000000000000000000000000000..1b1cb4d44c57c2d7a5122870fa6ac3e62ff7e94e GIT binary patch literal 8 KcmZQzfB*mh2mk>9 literal 0 HcmV?d00001 diff --git a/RFS/test-resources/snapshots/ES_7_10_BWC_Check/indices/6f5_qLyfQu-MKqe5IEJGuQ/0/__7d8i9c5gTH62_a-mtjnh1g b/RFS/test-resources/snapshots/ES_7_10_BWC_Check/indices/6f5_qLyfQu-MKqe5IEJGuQ/0/__7d8i9c5gTH62_a-mtjnh1g new file mode 100644 index 0000000000000000000000000000000000000000..b16f2a5007b03287c22c676f1e0daf530c8f3c6e GIT binary patch literal 479 zcmcD&o+B>qQ<|KbmuhO@oS$2eUz(TVnpaYknOe*M1d7E8JH9)<;>h+eYBrs0aV@(D(?kyNd;7J22{`i zBv=9!ya5%w4L8XE=+TrisP!zHA@YnCX!1~(u)c=s_k_!X0;(hzD$iyD)z1eCD5xO2 o6I7Ew$WKt4*e5~-yMfNjg9>uUKm?h(4rok%0ad`@wt{~i0LUFx;Q#;t literal 0 HcmV?d00001 diff --git a/RFS/test-resources/snapshots/ES_7_10_BWC_Check/indices/6f5_qLyfQu-MKqe5IEJGuQ/0/__xdhJGeuxSAGPk5gBj8PlfA b/RFS/test-resources/snapshots/ES_7_10_BWC_Check/indices/6f5_qLyfQu-MKqe5IEJGuQ/0/__xdhJGeuxSAGPk5gBj8PlfA new file mode 100644 index 0000000000000000000000000000000000000000..a382a81559d3ee52e31ba3e1f670f074a8ec8cc7 GIT binary patch literal 2742 zcmcImU1%It6uv(@`!h9S+QwM?VO%Qs5M-=vk`^SI#$YtsK%;^R6pCJa`q>%KOO&>9McM)trIlX6gi@s)QsZN{K$MP- zC?_sGeEyeACFJj@)Ii_^YB`4&qC^JaspO?NkRpaVu%x{a*xK52d5%!Vc!B3(LBxdq z=GfYgCUjS%b757i;v#yX$srTt!&eXfgczf0!XvYRs8^HJTP2HcLug%kh~cW?Z^IvT z6gL|PnQCcmYt%2tkB@9U)S7;|NpBU*)%|s2-@9gnJ;|GiDuA$4^5#vn{qo>>MB6)E zk1D4ZV<8qr+(>4EiUgQ^Zxdf%G2Q?v=L^BNF zQ6g+^=XjBp_Nvd6$Dzzwn(~qk`7+{@(1b~vesLcz^VmZ#} z(C|8$rcC?eXohn0?6*H)D8s63?(;zJWZ-@4su=@k{Y0vGwiA#rwnm2Nomwo?rdC>_1IzXq z+i5#x8OXXQA9Ko!OYI(_cbsueUsfqV9U!E}Su82!L z{C@6b^yzyh4(u8LS!^k|t}1=>$)~>}T&GHD_c55g{m=mz3yY1SAdy6%>V=aM+~iY( z!8R#|8QDKy{oBH&?9D1R?xx*iF07^JD(mg(q`0F%tHG2Ji5=FSPQz1L9P*aqpy9`B9(*@6 zu;e;fyEhF+5jEqA;7|+=4>a)bWDBA&cY9{F(r#@L-kEdv%96J7Q08w3xXHwkm5;l= KtTs-3e(^u|xpuJt literal 0 HcmV?d00001 diff --git a/RFS/test-resources/snapshots/ES_7_10_BWC_Check/indices/6f5_qLyfQu-MKqe5IEJGuQ/0/index-73ZKrS4iTc6nKzY0E4kC1w b/RFS/test-resources/snapshots/ES_7_10_BWC_Check/indices/6f5_qLyfQu-MKqe5IEJGuQ/0/index-73ZKrS4iTc6nKzY0E4kC1w new file mode 100644 index 0000000000000000000000000000000000000000..47c99188c4b742bccf9553f0688a2b951c8ee691 GIT binary patch literal 1245 zcmZ`(&rcIU6z+nBQcz4VdNDB)OhnVowy@pBi?+1ohZU*?MK0smo$gM%JG1W0Lh)jv z7%}L<_z!s3gYl#uP>!BF`UiM1UOXyojPCRYAp|Db-Fe@>@6DU{zM0G4>{ES=K$lsR zvrs4`T^fys>+5A~Blf5Mh(HG|tpG4@nfmqdWv%G?H9QAvlV1L&X+CqUHHJ&j2Es1` z6q(`2HX+J-ersxmE*PF*HNR6D8GLm`)}Dj5)kQthm{ZfhI?eZDq0* z+aoY}a0nr~ML(h5*YisYiw;l5^czd7_pq~?o?$H^FfcYb()TWtU4e=XwFBZz{XOzQ zNGQ@_1lx@6)6E5GEYjN)jwnK(5RMc8T|n9AI2`E|_FsDlLTBFj3QXF^92H=w=eSM9 zQE8qEmtw*t<+KB9z$Xlr5r96Y02^Sp*tQSL#)Y-$4E$HvK|h6~fxYqQ1byfJax zH4_P7#!^ELCcq0$4JOC{4BZ2SO3HwRSs;M578A~a<)v$Ud|?hN`ApvBxpX0UJt~&( z5cX=p{rKWjV`pRcVyJI=Wftq0^(%h@l^opR!!L_Ng>`tVcb+o~dcmGJfgM7;XmLx-z~r1Q#R(DiR-Rl$NE*xIjm{wp+J#bc4agn8r!mCU%IOu0ujd zdnLF*n}WXTQp5rO5*pipVx1m=k=M-&Vd9Y&|@~` zu~ z5j7NnA~#HQ*FnVMc52t!y@rh%Ef%=NrsETsyYGoQME0ZGZuZ97>aveHM+975Dd@5$ zD;w))m)Zc#*_J*(c3G=?K?l#m&N;t&!Lmw)@DPT}sU1%$Mb#$MX-;iQHr-8e-$fh( z8#4QM{MngMwb5$OKm_TzICer3W z#8PsAvUnAfptGY1+fZ&JVo-l1Z%~iVd5BCErbl`Uk@SNZRaWH8?k?tr`y)8fg-?#} za-y>Ocs%<5Ay1H$!>smb0wHq+$P){$d&Z&=#NsJtWO;X>5Tz08} zk`u-H0;t!D#X{`uvBzJ8Tw;uVd{+wn3mc|m*i$7Gbn5w1t)*HMO}*xr`BJw>SUI)$ zv@)4dR5GUO|1q%F1B*dcy{=c678YHeOY7&Cmak!Vxm00Y7a2HJP7Ob=6x&d7p!T0U z)!*A+3jY&*Mp$EVi|Hq%Q;DI-b@2zo!gVPG27t0<#Pl|Q{92>p5gD==vb^SA(G zgL@n*?n-nkJc9 zTXV+vCC|!cftAjWx|jezY_3Y0Ewgi=5e?siwZbGENTf|xk6 zK#)ZFI}t_xLjFR2g1y^heRq6_?dHwfdGF1v|4pAQaKT{kG6STHB5gDpb8E}=2k!Qqosb=QI^OG}! z6rn8@i1XVS_PP{YNiP4=-5?61Fn%4yQ5=T9Duy5R88nd{qCurRp=P7`^Kq-v z+6d~YO3NN+z=)t3>^z7!sy^m9X9t?MgQMM4?}gAM`DVBEi7DRyQ8DV!l|NwHQP6CL zt(H5lw_+ytlrWjtk=Ih7k%O_rL<$6f_7n>RZG-{3Gvt_p-K#3++;muP&3>I3D+}w~ zSZSV7T@VDFnaR!6MqQ<|KbmuhO@oS$2eUz(TVnpaYknOe*M1d7E8JH9)<;>h+eY? zi(Yn0E=URp^dJ;NKYu*L3=5NZ1HFQLuvVblUZ{KwNK+<+!zc+AbYam;gPFt_3l*G) zVp2+eGE~!VsJtJFd`TwMB}|@B`Lir~d1WaO4zn0k&>Brs0aQK^D(?kyNd;7JHdN37 zBv=9!ybTq+2{*|A=+TrisP!ycAo7eBX!1~(u)cxn_k_!X0;(hzD$iyL)z1wID5xO2 o15}eg$WKt4*!!V^-9YE%K?OOaAc9O?2Q((XfGS|{RQl}?0J1k#?*IS* literal 0 HcmV?d00001 diff --git a/RFS/test-resources/snapshots/ES_7_10_BWC_Check/indices/rtO3hIcQREynKwRVke75sQ/0/__q7cUOllVStaQMJVUtgWEPQ b/RFS/test-resources/snapshots/ES_7_10_BWC_Check/indices/rtO3hIcQREynKwRVke75sQ/0/__q7cUOllVStaQMJVUtgWEPQ new file mode 100644 index 0000000000000000000000000000000000000000..49adfd10cc6b4dce69d5b414f8c6227362fa5227 GIT binary patch literal 2740 zcmcImO>7%Q6rLZi?YOa2r_fUIw-}H(RA^h$G>KG2G?5`~fk=(o0|&F+9fwuy-LSjP zj|h^fkPu3_&?0dMaj1k;4oHa8azaQTP6(+;ITeI@pb{63<-PGtGIs2UL;7TU-gw^o zX5RbWyxp1Kn#Ufw*!DyyPCK(vYb9!j{+ye-1mv0It#AK*`Cf7P)sxrmfB(xNG6U9+ zb*(2S7NQ_blUfwF-1Idu!~;+$dhv4?=0G2zw392+4yY&{`3okLD(#dSUwQzdbaX^{ zBYWY-UtN`uH@{?`Bk*x`obiPyNrP}Hxe^Ddh+zhnv_FE9wyrxCBb4VD&lfnHh?v;V zRmSg|*gc`nhrU?HQ}kn#QznM{@u#;DA+wjQi`r12Cs+ZknTO@d?{BGkKTDVRfF9apn zTu@*lWml!<-+Eb(Q(8eI6qvLB3#L1q#ux;aJ1{Ujotd}w=0Dq*w?}nV@8nHY!hSh3 zf!2P#HI6`icU`r#{Yo6Y9#`A<^&8nPATdJ^F=9GFHhddx6kF%j__LXcd*{De zLZ5+8#GwrXAd4LZ*F(|d7Wn|-b|{jK$0+N)PaJ@;kZBYJi4_E@J~$bHNnRQZw~^~+ zWPe{ddkc>;)}?F0k&Ru>0!!0Ule*zUz*PcDd9I_bx9_dVgohJ0Np>M|H+ zmb4pJf+2QeI*WBZoE;4w}uu{u9J0e z+h7#X<~+fH3=I!uP+t{s5=3F{;p}S3Mr{$kv**FlqFQ+VVSt;Jcwy}N*XI2F>Ce9V E587{T0RR91 literal 0 HcmV?d00001 diff --git a/RFS/test-resources/snapshots/ES_7_10_BWC_Check/indices/rtO3hIcQREynKwRVke75sQ/0/index-OSYnb8w3SKmTqQ_p7m84JA b/RFS/test-resources/snapshots/ES_7_10_BWC_Check/indices/rtO3hIcQREynKwRVke75sQ/0/index-OSYnb8w3SKmTqQ_p7m84JA new file mode 100644 index 0000000000000000000000000000000000000000..2a58d7c0b7141a9c7f24e86068433f9c7398c702 GIT binary patch literal 1245 zcmZ`(&2JMq6wj1Ro2KPMVzql&X|+<3Kq$kcflT1SrpcsDDJ1Fi3lK8yj5Fh8#-7@q zH0h<%E{Lvn_ryQIkt5;+7X$~+t37ezj<|57q(U&xM^#m=4<5hYyx)7z?`Qk^JMZUl zPGG=YDtIgwQ?6Y|#=8&d*h74``zL`uT5ACy(yIk?9&gmv3$?aoZeA@0;bQ)u!0m8s zK@Uj3GDnV&h~Oae&_l!#?$r46N0y7MCJ+5mI%v=g$?OD>3Bd6dI(K4wFkbz&$*>TJ zfb~u>r|PP<<0Aoq3%UFChnLr*A``>lQH{yp`2823^B)tlD9(6z%V*96HHH%SosZy(&Yjx*l-3SYs@0|590W8`w zCddXHZ2&?QZPLYDP}b=)+lxYDntscin_X)#Tfec<&Q>>*GX0S7`uyV$y+Whu{r{Kf zUNcRAS$dwvrs7JidTQ*q&&>7F1h^*pyA?Z5oJ5fXICD z#^m4!#)?%PPVRRHV^BTi|~ zStJ#lUtsGkGh4Bp8Ka-AFm>ux(P+Yk+uAxpwtk2W-CC}A-ij$;?dJT-vT#<7YHbjL z7p9hO3_xyT9)qTi@~LEutJ<&++femw&knS#%);6ezk_ WcaFXTDFRd4-rnB9KHlCrf9*TQ5V_z0 literal 0 HcmV?d00001 diff --git a/RFS/test-resources/snapshots/ES_7_10_BWC_Check/indices/rtO3hIcQREynKwRVke75sQ/0/snap-rNzQqxl5Qrm99ZzB44Yz0w.dat b/RFS/test-resources/snapshots/ES_7_10_BWC_Check/indices/rtO3hIcQREynKwRVke75sQ/0/snap-rNzQqxl5Qrm99ZzB44Yz0w.dat new file mode 100644 index 0000000000000000000000000000000000000000..3c0ed3e72cb63d5cdc0192880d63bd6d9228cc32 GIT binary patch literal 1154 zcmZuwL2uhO7`4(lcATUc&|+Ec6x883jp2lYyBGTG>tyH?^k&nAJj_jN+mvo<7$5L$C`0q>791CdLh}` zAjPu)2?#vMz4P?X3$bd~)*}lMR4$pw4G$l5y^>SG&-nlY9a4ntaItaM($xtud6qF%*86)53 z%ajFBr~$Q6?!IAe0kdHkmDI^+Km0A_lHh^TF!FZQ-_z zMssD*BfOg5{wek^5#cU>VUH-v@bX|#oF`!-AIGG)(@^&~RVKg6o zC8k_r&Pgye{-IChT}f_5NHGzL_Hh7vAR-((2*5~CfbHa>CQgmb6{ZD)g!|M5QH1S} z!d3~R##X)AFn1jHfn!8VTHsy_Faa!Xc}$QEINAe*D%zBXdF)<)!0c@bjcNLZSzXy_ gGh1KV>y;Y&IeGkuaM8%W{8V5{-y9ndJ5h5!Hn literal 0 HcmV?d00001 diff --git a/RFS/test-resources/snapshots/ES_7_10_BWC_Check/indices/rtO3hIcQREynKwRVke75sQ/meta-AjJBKpIBKBXpMe1tfd-g.dat b/RFS/test-resources/snapshots/ES_7_10_BWC_Check/indices/rtO3hIcQREynKwRVke75sQ/meta-AjJBKpIBKBXpMe1tfd-g.dat new file mode 100644 index 0000000000000000000000000000000000000000..314252e1623f8be81bee78ccdae6c64d8ec9e764 GIT binary patch literal 535 zcmZ8e%T60H6b(phSg>V_P#1JTHHm^IVFMyGYAGN>L}6z+GdEx{V_WtOO?F6y@DLBt zhxiRX0kPl%*zgPd08(OaaAu|y;oUv=_?&z0oqLSN#~2TxJsktmkRr|HaznEpM@P(Q z<3~V}9?6^T9w^NOzrTp7l#Fka47j`0fan1Iid@i$Q4RlrDNk?N7?cLZ|aV zSoQOsS16b5QMMJ`Gv`z_7%Hkd1UnMUiF1{pkbyScKyU<(=I5YQL1?2rK!y>R^|Z3q z_Pg2s%<*8vq%hW=NyXws6;!NycYPO%=nfw+A`v9((q`Z5ZFnow+bdhUtF>yyD@1&A oX|=fUz1Fv9N;syA;I7&f#vba9Mu;b^y`B2~V~MH(1uWfkSu4$len6(jr~)SZX2Z`QH832 zSa6w&GazvVjxh7R;d@#q-Qku0`_JF+J^T5e{LZaH08csaMx$}#+5Ou$aUPI|0m9jl zuuf|Adzs`T2g0(^NT$8vR%V+3tefm~@=pgZcMsc79uK}>=deTNBdvPXJD#pxkvS8^%JCJJZL3Qc`guxD{ zHG*H&sOVETI%96gZR%Rh^9^K$$z{S_>yh`T1ve%fE%A)oz68tdgu%oJ{9>#&!h$48 zQ;?7g%7_}FYrA_ciJ3X2ML