Skip to content

Commit be68d35

Browse files
committed
type and id are lost upon serialization of Translog.Delete. (#24586)
This was introduced in #24460: the constructor of `Translog.Delete` that takes a `StreamInput` does not set the type and id. To make it a bit more robust, I made fields final so that forgetting to set them would make the compiler complain.
1 parent bdd889e commit be68d35

File tree

3 files changed

+46
-13
lines changed

3 files changed

+46
-13
lines changed

core/src/main/java/org/elasticsearch/index/translog/Translog.java

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.elasticsearch.common.util.concurrent.ReleasableLock;
4242
import org.elasticsearch.index.VersionType;
4343
import org.elasticsearch.index.engine.Engine;
44+
import org.elasticsearch.index.mapper.Uid;
4445
import org.elasticsearch.index.shard.AbstractIndexShardComponent;
4546
import org.elasticsearch.index.shard.IndexShardComponent;
4647

@@ -54,6 +55,7 @@
5455
import java.nio.file.StandardOpenOption;
5556
import java.util.ArrayList;
5657
import java.util.List;
58+
import java.util.Objects;
5759
import java.util.Optional;
5860
import java.util.Set;
5961
import java.util.concurrent.atomic.AtomicBoolean;
@@ -975,17 +977,29 @@ public long getAutoGeneratedIdTimestamp() {
975977
}
976978

977979
public static class Delete implements Operation {
978-
public static final int SERIALIZATION_FORMAT = 2; // since 2.0-beta1 and 1.1
980+
public static final int FORMAT_5_0 = 2; // 5.0 - 5.5
981+
private static final int FORMAT_SINGLE_TYPE = FORMAT_5_0 + 1; // 5.5 - 6.0
979982

980-
private String type, id;
983+
private final String type, id;
981984
private final Term uid;
982985
private final long version;
983986
private final VersionType versionType;
984987

985988
public Delete(StreamInput in) throws IOException {
986989
final int format = in.readVInt();// SERIALIZATION_FORMAT
987-
assert format == SERIALIZATION_FORMAT : "format was: " + format;
988-
uid = new Term(in.readString(), in.readString());
990+
assert format >= FORMAT_5_0 && format <= FORMAT_SINGLE_TYPE : "format was: " + format;
991+
if (format >= FORMAT_SINGLE_TYPE) {
992+
type = in.readString();
993+
id = in.readString();
994+
uid = new Term(in.readString(), in.readString());
995+
} else {
996+
uid = new Term(in.readString(), in.readString());
997+
// the uid was constructed from the type and id so we can
998+
// extract them back
999+
Uid uidObject = Uid.createUid(uid.text());
1000+
type = uidObject.type();
1001+
id = uidObject.id();
1002+
}
9891003
this.version = in.readLong();
9901004
this.versionType = VersionType.fromValue(in.readByte());
9911005
assert versionType.validateVersionForWrites(this.version);
@@ -1000,8 +1014,8 @@ public Delete(String type, String id, Term uid) {
10001014
}
10011015

10021016
public Delete(String type, String id, Term uid, long version, VersionType versionType) {
1003-
this.type = type;
1004-
this.id = id;
1017+
this.type = Objects.requireNonNull(type);
1018+
this.id = Objects.requireNonNull(id);
10051019
this.uid = uid;
10061020
this.version = version;
10071021
this.versionType = versionType;
@@ -1044,7 +1058,9 @@ public Source getSource() {
10441058

10451059
@Override
10461060
public void writeTo(StreamOutput out) throws IOException {
1047-
out.writeVInt(SERIALIZATION_FORMAT);
1061+
out.writeVInt(FORMAT_SINGLE_TYPE);
1062+
out.writeString(type);
1063+
out.writeString(id);
10481064
out.writeString(uid.field());
10491065
out.writeString(uid.text());
10501066
out.writeLong(version);

core/src/test/java/org/elasticsearch/index/engine/InternalEngineTests.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1720,20 +1720,20 @@ public void testBasicCreatedFlag() throws IOException {
17201720
indexResult = engine.index(index);
17211721
assertFalse(indexResult.isCreated());
17221722

1723-
engine.delete(new Engine.Delete(null, "1", newUid(doc)));
1723+
engine.delete(new Engine.Delete("doc", "1", newUid(doc)));
17241724

17251725
index = indexForDoc(doc);
17261726
indexResult = engine.index(index);
17271727
assertTrue(indexResult.isCreated());
17281728
}
17291729

17301730
public void testCreatedFlagAfterFlush() throws IOException {
1731-
ParsedDocument doc = testParsedDocument("1", "test", null, -1, -1, testDocument(), B_1, null);
1731+
ParsedDocument doc = testParsedDocument("1", "doc", null, -1, -1, testDocument(), B_1, null);
17321732
Engine.Index index = indexForDoc(doc);
17331733
Engine.IndexResult indexResult = engine.index(index);
17341734
assertTrue(indexResult.isCreated());
17351735

1736-
engine.delete(new Engine.Delete(null, "1", newUid(doc)));
1736+
engine.delete(new Engine.Delete("doc", "1", newUid(doc)));
17371737

17381738
engine.flush();
17391739

core/src/test/java/org/elasticsearch/index/translog/TranslogTests.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import org.elasticsearch.index.VersionType;
5151
import org.elasticsearch.index.mapper.ParsedDocument;
5252
import org.elasticsearch.index.mapper.Uid;
53+
import org.elasticsearch.index.mapper.UidFieldMapper;
5354
import org.elasticsearch.index.shard.ShardId;
5455
import org.elasticsearch.index.translog.Translog.Location;
5556
import org.elasticsearch.test.ESTestCase;
@@ -298,21 +299,21 @@ public void testStats() throws IOException {
298299
assertThat(stats.estimatedNumberOfOperations(), equalTo(0L));
299300
assertThat(stats.getTranslogSizeInBytes(), equalTo(firstOperationPosition));
300301
assertEquals(6, total.estimatedNumberOfOperations());
301-
assertEquals(455, total.getTranslogSizeInBytes());
302+
assertEquals(476, total.getTranslogSizeInBytes());
302303

303304
BytesStreamOutput out = new BytesStreamOutput();
304305
total.writeTo(out);
305306
TranslogStats copy = new TranslogStats();
306307
copy.readFrom(out.bytes().streamInput());
307308

308309
assertEquals(6, copy.estimatedNumberOfOperations());
309-
assertEquals(455, copy.getTranslogSizeInBytes());
310+
assertEquals(476, copy.getTranslogSizeInBytes());
310311

311312
try (XContentBuilder builder = XContentFactory.jsonBuilder()) {
312313
builder.startObject();
313314
copy.toXContent(builder, ToXContent.EMPTY_PARAMS);
314315
builder.endObject();
315-
assertEquals("{\"translog\":{\"operations\":6,\"size_in_bytes\":455}}", builder.string());
316+
assertEquals("{\"translog\":{\"operations\":6,\"size_in_bytes\":476}}", builder.string());
316317
}
317318

318319
try {
@@ -1925,4 +1926,20 @@ public void testPendingDelete() throws IOException {
19251926
public static Translog.Location randomTranslogLocation() {
19261927
return new Translog.Location(randomLong(), randomLong(), randomInt());
19271928
}
1929+
1930+
public void testSerialization() throws Exception {
1931+
// simulate legacy delete serialization
1932+
BytesStreamOutput out = new BytesStreamOutput();
1933+
out.writeVInt(Translog.Delete.FORMAT_5_0);
1934+
out.writeString(UidFieldMapper.NAME);
1935+
out.writeString("my_type#my_id");
1936+
out.writeLong(3); // version
1937+
out.writeByte(VersionType.INTERNAL.getValue());
1938+
out.writeLong(2); // seq no
1939+
out.writeLong(0); // primary term
1940+
StreamInput in = out.bytes().streamInput();
1941+
Translog.Delete serializedDelete = new Translog.Delete(in);
1942+
assertEquals("my_type", serializedDelete.type());
1943+
assertEquals("my_id", serializedDelete.id());
1944+
}
19281945
}

0 commit comments

Comments
 (0)