Skip to content

Commit f7143b8

Browse files
committed
Fix Joda compatibility in stream protocol (#53823)
The JodaCompatibleZonedDateTime is a compatibility object that unions Joda's DateTime and Java's ZonedDateTime, meant for use in scripts. When it was added, we serialized the JCZDT as a Joda DateTime so that when sending to older nodes they could still read the object. However, on newer nodes, we continued also reading this as a Joda DateTime. This commit changes the read side to form a JCZDT. closes #53586
1 parent 8a0bb6d commit f7143b8

File tree

2 files changed

+18
-4
lines changed

2 files changed

+18
-4
lines changed

server/src/main/java/org/elasticsearch/common/io/stream/StreamInput.java

+8-4
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,10 @@
3838
import org.elasticsearch.common.geo.GeoPoint;
3939
import org.elasticsearch.common.settings.SecureString;
4040
import org.elasticsearch.common.text.Text;
41+
import org.elasticsearch.common.time.DateUtils;
4142
import org.elasticsearch.common.unit.TimeValue;
4243
import org.elasticsearch.common.util.concurrent.EsRejectedExecutionException;
43-
import org.joda.time.DateTime;
44+
import org.elasticsearch.script.JodaCompatibleZonedDateTime;
4445
import org.joda.time.DateTimeZone;
4546

4647
import java.io.ByteArrayInputStream;
@@ -769,9 +770,12 @@ private List readArrayList() throws IOException {
769770
return list;
770771
}
771772

772-
private DateTime readDateTime() throws IOException {
773-
final String timeZoneId = readString();
774-
return new DateTime(readLong(), DateTimeZone.forID(timeZoneId));
773+
private JodaCompatibleZonedDateTime readDateTime() throws IOException {
774+
// we reuse DateTime to communicate with older nodes that don't know about the joda compat layer, but
775+
// here we are on a new node so we always want a compat datetime
776+
final ZoneId zoneId = DateUtils.dateTimeZoneToZoneId(DateTimeZone.forID(readString()));
777+
long millis = readLong();
778+
return new JodaCompatibleZonedDateTime(Instant.ofEpochMilli(millis), zoneId);
775779
}
776780

777781
private ZonedDateTime readZonedDateTime() throws IOException {

server/src/test/java/org/elasticsearch/common/io/stream/BytesStreamsTests.java

+10
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,14 @@
2727
import org.elasticsearch.common.lucene.BytesRefs;
2828
import org.elasticsearch.common.unit.TimeValue;
2929
import org.elasticsearch.common.util.PageCacheRecycler;
30+
import org.elasticsearch.script.JodaCompatibleZonedDateTime;
3031
import org.elasticsearch.test.ESTestCase;
32+
import org.joda.time.DateTime;
3133
import org.joda.time.DateTimeZone;
3234

3335
import java.io.EOFException;
3436
import java.io.IOException;
37+
import java.time.ZoneId;
3538
import java.util.ArrayList;
3639
import java.util.Collections;
3740
import java.util.HashMap;
@@ -49,6 +52,7 @@
4952
import static org.hamcrest.Matchers.endsWith;
5053
import static org.hamcrest.Matchers.equalTo;
5154
import static org.hamcrest.Matchers.hasSize;
55+
import static org.hamcrest.Matchers.instanceOf;
5256
import static org.hamcrest.Matchers.is;
5357
import static org.hamcrest.Matchers.nullValue;
5458

@@ -303,6 +307,7 @@ public void testSimpleStreams() throws Exception {
303307
out.writeTimeZone(DateTimeZone.forID("CET"));
304308
out.writeOptionalTimeZone(DateTimeZone.getDefault());
305309
out.writeOptionalTimeZone(null);
310+
out.writeGenericValue(new DateTime(123456, DateTimeZone.forID("America/Los_Angeles")));
306311
final byte[] bytes = BytesReference.toBytes(out.bytes());
307312
StreamInput in = StreamInput.wrap(BytesReference.toBytes(out.bytes()));
308313
assertEquals(in.available(), bytes.length);
@@ -335,6 +340,11 @@ public void testSimpleStreams() throws Exception {
335340
assertEquals(DateTimeZone.forID("CET"), in.readTimeZone());
336341
assertEquals(DateTimeZone.getDefault(), in.readOptionalTimeZone());
337342
assertNull(in.readOptionalTimeZone());
343+
Object dt = in.readGenericValue();
344+
assertThat(dt, instanceOf(JodaCompatibleZonedDateTime.class));
345+
JodaCompatibleZonedDateTime jdt = (JodaCompatibleZonedDateTime) dt;
346+
assertThat(jdt.getZonedDateTime().toInstant().toEpochMilli(), equalTo(123456L));
347+
assertThat(jdt.getZonedDateTime().getZone(), equalTo(ZoneId.of("America/Los_Angeles")));
338348
assertEquals(0, in.available());
339349
in.close();
340350
out.close();

0 commit comments

Comments
 (0)