-
Notifications
You must be signed in to change notification settings - Fork 30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixed bug in mapping parsing; added tests #1023
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
package org.opensearch.migrations.bulkload.transformers; | ||
|
||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import com.fasterxml.jackson.databind.node.ArrayNode; | ||
import com.fasterxml.jackson.databind.node.ObjectNode; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import lombok.extern.slf4j.Slf4j; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
|
||
@Slf4j | ||
public class TransformFunctionsTest { | ||
|
||
@Test | ||
public void removeIntermediateMappingsLevels_AsExpected() throws Exception { | ||
// Extract from {"mappings":[{"_doc":{"properties":{"address":{"type":"text"}}}}]) | ||
ObjectNode testNode1 = new ObjectMapper().createObjectNode(); | ||
ArrayNode mappingsNode1 = new ObjectMapper().createArrayNode(); | ||
ObjectNode docNode1 = new ObjectMapper().createObjectNode(); | ||
ObjectNode propertiesNode1 = new ObjectMapper().createObjectNode(); | ||
ObjectNode addressNode1 = new ObjectMapper().createObjectNode(); | ||
addressNode1.put("type", "text"); | ||
propertiesNode1.set("address", addressNode1); | ||
docNode1.set(TransformFunctions.PROPERTIES_KEY_STR, propertiesNode1); | ||
ObjectNode intermediateNode1 = new ObjectMapper().createObjectNode(); | ||
intermediateNode1.set("_doc", docNode1); | ||
mappingsNode1.add(intermediateNode1); | ||
Comment on lines
+18
to
+28
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could you replace this w/ inline json that gets parsed?
It's a lot easier to read and to maintain. You can copy-paste literal json from a text editor into your IDE and it should do all of the necessary escaping (IntelliJ does this, I'd hope eclipse & vscode do too). Then you can just new |
||
testNode1.set(TransformFunctions.MAPPINGS_KEY_STR, mappingsNode1); | ||
|
||
TransformFunctions.removeIntermediateMappingsLevels(testNode1); | ||
assertEquals(docNode1.toString(), testNode1.get(TransformFunctions.MAPPINGS_KEY_STR).toString()); | ||
|
||
// Extract from {"mappings":[{"properties":{"address":{"type":"text"}}}]) | ||
ObjectNode testNode2 = new ObjectMapper().createObjectNode(); | ||
ArrayNode mappingsNode2 = new ObjectMapper().createArrayNode(); | ||
ObjectNode propertiesNode2 = new ObjectMapper().createObjectNode(); | ||
ObjectNode addressNode2 = new ObjectMapper().createObjectNode(); | ||
addressNode2.put("type", "text"); | ||
propertiesNode2.set("address", addressNode2); | ||
ObjectNode intermediateNode2 = new ObjectMapper().createObjectNode(); | ||
intermediateNode2.set(TransformFunctions.PROPERTIES_KEY_STR, propertiesNode2); | ||
mappingsNode2.add(intermediateNode2); | ||
testNode2.set(TransformFunctions.MAPPINGS_KEY_STR, mappingsNode2); | ||
|
||
TransformFunctions.removeIntermediateMappingsLevels(testNode2); | ||
assertEquals(intermediateNode2.toString(), testNode2.get(TransformFunctions.MAPPINGS_KEY_STR).toString()); | ||
|
||
// Extract from {"mappings":[]) | ||
ObjectNode testNode3 = new ObjectMapper().createObjectNode(); | ||
ArrayNode mappingsNode3 = new ObjectMapper().createArrayNode(); | ||
testNode3.set(TransformFunctions.MAPPINGS_KEY_STR, mappingsNode3); | ||
|
||
TransformFunctions.removeIntermediateMappingsLevels(testNode3); | ||
assertEquals(new ObjectMapper().createObjectNode().toString(), testNode3.get(TransformFunctions.MAPPINGS_KEY_STR).toString()); | ||
} | ||
|
||
@Test | ||
public void getMappingsFromBeneathIntermediate_AsExpected() throws Exception { | ||
// Extract from {"_doc":{"properties":{"address":{"type":"text"}}}} | ||
ObjectNode testNode1 = new ObjectMapper().createObjectNode(); | ||
ObjectNode docNode1 = new ObjectMapper().createObjectNode(); | ||
ObjectNode propertiesNode1 = new ObjectMapper().createObjectNode(); | ||
ObjectNode addressNode1 = new ObjectMapper().createObjectNode(); | ||
addressNode1.put("type", "text"); | ||
propertiesNode1.set("address", addressNode1); | ||
docNode1.set(TransformFunctions.PROPERTIES_KEY_STR, propertiesNode1); | ||
testNode1.set("_doc", docNode1); | ||
|
||
ObjectNode result1 = TransformFunctions.getMappingsFromBeneathIntermediate(testNode1); | ||
assertEquals(docNode1.toString(), result1.toString()); | ||
|
||
// Extract from {"arbitrary_type":{"properties":{"address":{"type":"text"}}}} | ||
ObjectNode testNode2 = new ObjectMapper().createObjectNode(); | ||
ObjectNode docNode2 = new ObjectMapper().createObjectNode(); | ||
ObjectNode propertiesNode2 = new ObjectMapper().createObjectNode(); | ||
ObjectNode addressNode2 = new ObjectMapper().createObjectNode(); | ||
addressNode2.put("type", "text"); | ||
propertiesNode2.set("address", addressNode2); | ||
docNode2.set(TransformFunctions.PROPERTIES_KEY_STR, propertiesNode2); | ||
testNode2.set("arbitrary_type", docNode2); | ||
|
||
ObjectNode result2 = TransformFunctions.getMappingsFromBeneathIntermediate(testNode2); | ||
assertEquals(docNode2.toString(), result2.toString()); | ||
|
||
// Extract from {"properties":{"address":{"type":"text"}} | ||
ObjectNode testNode3 = new ObjectMapper().createObjectNode(); | ||
ObjectNode propertiesNode3 = new ObjectMapper().createObjectNode(); | ||
ObjectNode addressNode3 = new ObjectMapper().createObjectNode(); | ||
addressNode3.put("type", "text"); | ||
propertiesNode3.set("address", addressNode3); | ||
testNode3.set(TransformFunctions.PROPERTIES_KEY_STR, propertiesNode3); | ||
|
||
ObjectNode result3 = TransformFunctions.getMappingsFromBeneathIntermediate(testNode3); | ||
assertEquals(testNode3.toString(), result3.toString()); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -345,7 +345,7 @@ 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. | ||
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. It also contains two indices with either no mappings or an empty mapping entry and no documents; this exercises an edge case where there will be a mappings entry in the snapshot with no contents. | ||
|
||
``` | ||
curl -X PUT "localhost:19200/_template/bwc_template?include_type_name=true" -H "Content-Type: application/json" -d ' | ||
|
@@ -426,12 +426,36 @@ curl -X PUT "localhost:19200/_index_template/fwc_template" -H "Content-Type: app | |
|
||
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 ' | ||
curl -X PUT "localhost:19200/fwc_alias/_doc/fwc_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/no_mappings_no_docs" -H "Content-Type: application/json" -d ' | ||
{ | ||
"settings": { | ||
"index": { | ||
"number_of_shards": 1, | ||
"number_of_replicas": 0 | ||
} | ||
} | ||
}' | ||
|
||
curl -X PUT "localhost:19200/empty_mappings_no_docs" -H "Content-Type: application/json" -d ' | ||
{ | ||
"settings": { | ||
"index": { | ||
"number_of_shards": 1, | ||
"number_of_replicas": 0 | ||
} | ||
}, | ||
"mappings": { | ||
"properties":{ | ||
} | ||
} | ||
}' | ||
Comment on lines
+435
to
+457
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd love to see us generate these on-the-fly and then cache them like we do for preloaded data images. In fact, use the preloaded images, then just take a snapshot via a helper program. Make the output of that something that gets cached as a build artifact and then it can become a dependency to the tests. It seems like that could be 1-2 hours of work and removes the risks of many hours of work trying to figure out if there was a mismatch later on. |
||
|
||
curl -X PUT "localhost:19200/_snapshot/test_repository" -H "Content-Type: application/json" -d '{ | ||
"type": "fs", | ||
"settings": { | ||
|
@@ -441,9 +465,8 @@ curl -X PUT "localhost:19200/_snapshot/test_repository" -H "Content-Type: applic | |
}' | ||
|
||
curl -X PUT "localhost:19200/_snapshot/test_repository/rfs-snapshot" -H "Content-Type: application/json" -d '{ | ||
"indices": "bwc_index_1,fwc_index_1", | ||
"indices": "bwc_index_1,fwc_index_1,no_mappings_no_docs,empty_mappings_no_docs", | ||
"ignore_unavailable": true, | ||
"include_global_state": true | ||
}' | ||
|
||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +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"}} | ||
{"snapshots":[{"name":"rfs-snapshot","uuid":"KhcpVj8aRMek0oLMUSPHeg","state":1,"index_metadata_lookup":{"zUFSBaZgSdKCPAS2xEfCww":"ndSIWVDSQpuC8xY2DieX7g-_na_-1-1-1","s_FgCb4gREmddVPRW-EtWw":"BI3xMNgnRe6HldftNpfxzQ-_na_-1-1-1","a5ONDmS2RmmN1GEZMRCJRg":"S0lxKX7vSLS7jzquAnNzdg-_na_-1-1-1","0edrmuSPR1CIr2B6BZbMJA":"tBmFXxGhTeiDlznQiKfNCA-_na_-1-1-1"},"version":"7.10.2"}],"indices":{"empty_mappings_no_docs":{"id":"zUFSBaZgSdKCPAS2xEfCww","snapshots":["KhcpVj8aRMek0oLMUSPHeg"],"shard_generations":["C7dK_wyqSUuDyKkefOXUUQ"]},"bwc_index_1":{"id":"0edrmuSPR1CIr2B6BZbMJA","snapshots":["KhcpVj8aRMek0oLMUSPHeg"],"shard_generations":["tGRrEPUKTuWK_eyviXSHvg"]},"fwc_index_1":{"id":"s_FgCb4gREmddVPRW-EtWw","snapshots":["KhcpVj8aRMek0oLMUSPHeg"],"shard_generations":["yaxW_gAlTNqirWlIIoil8A"]},"no_mappings_no_docs":{"id":"a5ONDmS2RmmN1GEZMRCJRg","snapshots":["KhcpVj8aRMek0oLMUSPHeg"],"shard_generations":["cbs2bGwwSy66JeQOO9vNbQ"]}},"min_version":"7.9.0","index_metadata_identifiers":{"ndSIWVDSQpuC8xY2DieX7g-_na_-1-1-1":"3liaNJIBxXZFvc_xLY-F","S0lxKX7vSLS7jzquAnNzdg-_na_-1-1-1":"31iaNJIBxXZFvc_xLY-F","BI3xMNgnRe6HldftNpfxzQ-_na_-1-1-1":"3ViaNJIBxXZFvc_xLY-F","tBmFXxGhTeiDlznQiKfNCA-_na_-1-1-1":"4FiaNJIBxXZFvc_xLY-F"}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is it appropriate to replace [] with "[{}]". Is this true for all versions of targets?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This results in an index creation call that looks like:
I'm not sure if the empty mappings blob is valid for ALL possible targets, but it does appear valid for the targets we currently consider - OS 1.X & OS 2.X