19
19
20
20
package org .elasticsearch .index .seqno ;
21
21
22
+ import org .elasticsearch .common .ParseField ;
22
23
import org .elasticsearch .common .io .stream .StreamInput ;
23
24
import org .elasticsearch .common .io .stream .StreamOutput ;
24
25
import org .elasticsearch .common .io .stream .Writeable ;
26
+ import org .elasticsearch .common .xcontent .ConstructingObjectParser ;
27
+ import org .elasticsearch .common .xcontent .ToXContent ;
28
+ import org .elasticsearch .common .xcontent .XContentBuilder ;
29
+ import org .elasticsearch .common .xcontent .XContentParser ;
25
30
26
31
import java .io .IOException ;
27
- import java .util .Arrays ;
28
- import java .util .Locale ;
29
32
import java .util .Objects ;
30
33
31
34
/**
34
37
* otherwise merge away operations that have been soft deleted). Each retention lease contains a unique identifier, the retaining sequence
35
38
* number, the timestamp of when the lease was created or renewed, and the source of the retention lease (e.g., "ccr").
36
39
*/
37
- public final class RetentionLease implements Writeable {
40
+ public final class RetentionLease implements ToXContent , Writeable {
38
41
39
42
private final String id ;
40
43
@@ -94,10 +97,6 @@ public RetentionLease(final String id, final long retainingSequenceNumber, final
94
97
if (id .isEmpty ()) {
95
98
throw new IllegalArgumentException ("retention lease ID can not be empty" );
96
99
}
97
- if (id .contains (":" ) || id .contains (";" ) || id .contains ("," )) {
98
- // retention lease IDs can not contain these characters because they are used in encoding retention leases
99
- throw new IllegalArgumentException ("retention lease ID can not contain any of [:;,] but was [" + id + "]" );
100
- }
101
100
if (retainingSequenceNumber < 0 ) {
102
101
throw new IllegalArgumentException ("retention lease retaining sequence number [" + retainingSequenceNumber + "] out of range" );
103
102
}
@@ -108,10 +107,6 @@ public RetentionLease(final String id, final long retainingSequenceNumber, final
108
107
if (source .isEmpty ()) {
109
108
throw new IllegalArgumentException ("retention lease source can not be empty" );
110
109
}
111
- if (source .contains (":" ) || source .contains (";" ) || source .contains ("," )) {
112
- // retention lease sources can not contain these characters because they are used in encoding retention leases
113
- throw new IllegalArgumentException ("retention lease source can not contain any of [:;,] but was [" + source + "]" );
114
- }
115
110
this .id = id ;
116
111
this .retainingSequenceNumber = retainingSequenceNumber ;
117
112
this .timestamp = timestamp ;
@@ -145,43 +140,49 @@ public void writeTo(final StreamOutput out) throws IOException {
145
140
out .writeString (source );
146
141
}
147
142
148
- /**
149
- * Encodes a retention lease as a string. This encoding can be decoded by {@link #decodeRetentionLease(String)}. The retention lease is
150
- * encoded in the format <code>id:{id};retaining_seq_no:{retainingSequenecNumber};timestamp:{timestamp};source:{source}</code>.
151
- *
152
- * @param retentionLease the retention lease
153
- * @return the encoding of the retention lease
154
- */
155
- static String encodeRetentionLease (final RetentionLease retentionLease ) {
156
- Objects .requireNonNull (retentionLease );
157
- return String .format (
158
- Locale .ROOT ,
159
- "id:%s;retaining_seq_no:%d;timestamp:%d;source:%s" ,
160
- retentionLease .id ,
161
- retentionLease .retainingSequenceNumber ,
162
- retentionLease .timestamp ,
163
- retentionLease .source );
143
+ private static final ParseField ID_FIELD = new ParseField ("id" );
144
+ private static final ParseField RETAINING_SEQUENCE_NUMBER_FIELD = new ParseField ("retaining_sequence_number" );
145
+ private static final ParseField TIMESTAMP_FIELD = new ParseField ("timestamp" );
146
+ private static final ParseField SOURCE_FIELD = new ParseField ("source" );
147
+
148
+ private static ConstructingObjectParser <RetentionLease , Void > PARSER = new ConstructingObjectParser <>(
149
+ "retention_leases" ,
150
+ (a ) -> new RetentionLease ((String ) a [0 ], (Long ) a [1 ], (Long ) a [2 ], (String ) a [3 ]));
151
+
152
+ static {
153
+ PARSER .declareString (ConstructingObjectParser .constructorArg (), ID_FIELD );
154
+ PARSER .declareLong (ConstructingObjectParser .constructorArg (), RETAINING_SEQUENCE_NUMBER_FIELD );
155
+ PARSER .declareLong (ConstructingObjectParser .constructorArg (), TIMESTAMP_FIELD );
156
+ PARSER .declareString (ConstructingObjectParser .constructorArg (), SOURCE_FIELD );
157
+ }
158
+
159
+ @ Override
160
+ public XContentBuilder toXContent (final XContentBuilder builder , final Params params ) throws IOException {
161
+ builder .startObject ();
162
+ {
163
+ builder .field (ID_FIELD .getPreferredName (), id );
164
+ builder .field (RETAINING_SEQUENCE_NUMBER_FIELD .getPreferredName (), retainingSequenceNumber );
165
+ builder .field (TIMESTAMP_FIELD .getPreferredName (), timestamp );
166
+ builder .field (SOURCE_FIELD .getPreferredName (), source );
167
+ }
168
+ builder .endObject ();
169
+ return builder ;
170
+ }
171
+
172
+ @ Override
173
+ public boolean isFragment () {
174
+ return false ;
164
175
}
165
176
166
177
/**
167
- * Decodes a retention lease encoded by {@link #encodeRetentionLease(RetentionLease)}.
178
+ * Parses a retention lease from {@link org.elasticsearch.common.xcontent.XContent}. This method assumes that the retention lease was
179
+ * converted to {@link org.elasticsearch.common.xcontent.XContent} via {@link #toXContent(XContentBuilder, Params)}.
168
180
*
169
- * @param encodedRetentionLease an encoded retention lease
170
- * @return the decoded retention lease
181
+ * @param parser the parser
182
+ * @return a retention lease
171
183
*/
172
- static RetentionLease decodeRetentionLease (final String encodedRetentionLease ) {
173
- Objects .requireNonNull (encodedRetentionLease );
174
- final String [] fields = encodedRetentionLease .split (";" );
175
- assert fields .length == 4 : Arrays .toString (fields );
176
- assert fields [0 ].matches ("id:[^:;,]+" ) : fields [0 ];
177
- final String id = fields [0 ].substring ("id:" .length ());
178
- assert fields [1 ].matches ("retaining_seq_no:\\ d+" ) : fields [1 ];
179
- final long retainingSequenceNumber = Long .parseLong (fields [1 ].substring ("retaining_seq_no:" .length ()));
180
- assert fields [2 ].matches ("timestamp:\\ d+" ) : fields [2 ];
181
- final long timestamp = Long .parseLong (fields [2 ].substring ("timestamp:" .length ()));
182
- assert fields [3 ].matches ("source:[^:;,]+" ) : fields [3 ];
183
- final String source = fields [3 ].substring ("source:" .length ());
184
- return new RetentionLease (id , retainingSequenceNumber , timestamp , source );
184
+ public static RetentionLease fromXContent (final XContentParser parser ) {
185
+ return PARSER .apply (parser , null );
185
186
}
186
187
187
188
@ Override
0 commit comments