Introduce Annotation.Builder class and use it to create instances of Annotation class (#56276) (#56286)

This commit is contained in:
Przemysław Witek 2020-05-06 20:47:03 +02:00 committed by GitHub
parent e852bb29b7
commit 0cd0ab276e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 173 additions and 138 deletions

View File

@ -30,42 +30,39 @@ public class Annotation implements ToXContentObject, Writeable {
public static final ParseField MODIFIED_USERNAME = new ParseField("modified_username");
public static final ParseField TYPE = new ParseField("type");
public static final ObjectParser<Annotation, Void> PARSER = new ObjectParser<>(TYPE.getPreferredName(), true, Annotation::new);
public static final ObjectParser<Builder, Void> PARSER = new ObjectParser<>(TYPE.getPreferredName(), true, Builder::new);
static {
PARSER.declareString(Annotation::setAnnotation, ANNOTATION);
PARSER.declareField(Annotation::setCreateTime,
PARSER.declareString(Builder::setAnnotation, ANNOTATION);
PARSER.declareField(Builder::setCreateTime,
p -> TimeUtils.parseTimeField(p, CREATE_TIME.getPreferredName()), CREATE_TIME, ObjectParser.ValueType.VALUE);
PARSER.declareString(Annotation::setCreateUsername, CREATE_USERNAME);
PARSER.declareField(Annotation::setTimestamp,
PARSER.declareString(Builder::setCreateUsername, CREATE_USERNAME);
PARSER.declareField(Builder::setTimestamp,
p -> TimeUtils.parseTimeField(p, TIMESTAMP.getPreferredName()), TIMESTAMP, ObjectParser.ValueType.VALUE);
PARSER.declareField(Annotation::setEndTimestamp,
PARSER.declareField(Builder::setEndTimestamp,
p -> TimeUtils.parseTimeField(p, END_TIMESTAMP.getPreferredName()), END_TIMESTAMP, ObjectParser.ValueType.VALUE);
PARSER.declareString(Annotation::setJobId, Job.ID);
PARSER.declareField(Annotation::setModifiedTime,
PARSER.declareString(Builder::setJobId, Job.ID);
PARSER.declareField(Builder::setModifiedTime,
p -> TimeUtils.parseTimeField(p, MODIFIED_TIME.getPreferredName()), MODIFIED_TIME, ObjectParser.ValueType.VALUE);
PARSER.declareString(Annotation::setModifiedUsername, MODIFIED_USERNAME);
PARSER.declareString(Annotation::setType, TYPE);
PARSER.declareString(Builder::setModifiedUsername, MODIFIED_USERNAME);
PARSER.declareString(Builder::setType, TYPE);
}
private String annotation;
private Date createTime;
private String createUsername;
private Date timestamp;
private Date endTimestamp;
private final String annotation;
private final Date createTime;
private final String createUsername;
private final Date timestamp;
private final Date endTimestamp;
/**
* Unlike most ML classes, this may be <code>null</code> or wildcarded
*/
private String jobId;
private Date modifiedTime;
private String modifiedUsername;
private String type;
private final String jobId;
private final Date modifiedTime;
private final String modifiedUsername;
private final String type;
private Annotation() {
}
public Annotation(String annotation, Date createTime, String createUsername, Date timestamp, Date endTimestamp, String jobId,
Date modifiedTime, String modifiedUsername, String type) {
private Annotation(String annotation, Date createTime, String createUsername, Date timestamp, Date endTimestamp, String jobId,
Date modifiedTime, String modifiedUsername, String type) {
this.annotation = Objects.requireNonNull(annotation);
this.createTime = Objects.requireNonNull(createTime);
this.createUsername = Objects.requireNonNull(createUsername);
@ -77,19 +74,6 @@ public class Annotation implements ToXContentObject, Writeable {
this.type = Objects.requireNonNull(type);
}
public Annotation(Annotation other) {
Objects.requireNonNull(other);
this.annotation = other.annotation;
this.createTime = new Date(other.createTime.getTime());
this.createUsername = other.createUsername;
this.timestamp = new Date(other.timestamp.getTime());
this.endTimestamp = other.endTimestamp == null ? null : new Date(other.endTimestamp.getTime());
this.jobId = other.jobId;
this.modifiedTime = other.modifiedTime == null ? null : new Date(other.modifiedTime.getTime());
this.modifiedUsername = other.modifiedUsername;
this.type = other.type;
}
public Annotation(StreamInput in) throws IOException {
annotation = in.readString();
createTime = new Date(in.readLong());
@ -131,81 +115,44 @@ public class Annotation implements ToXContentObject, Writeable {
}
out.writeOptionalString(modifiedUsername);
out.writeString(type);
}
public String getAnnotation() {
return annotation;
}
public void setAnnotation(String annotation) {
this.annotation = Objects.requireNonNull(annotation);
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = Objects.requireNonNull(createTime);
}
public String getCreateUsername() {
return createUsername;
}
public void setCreateUsername(String createUsername) {
this.createUsername = Objects.requireNonNull(createUsername);
}
public Date getTimestamp() {
return timestamp;
}
public void setTimestamp(Date timestamp) {
this.timestamp = Objects.requireNonNull(timestamp);
}
public Date getEndTimestamp() {
return endTimestamp;
}
public void setEndTimestamp(Date endTimestamp) {
this.endTimestamp = endTimestamp;
}
public String getJobId() {
return jobId;
}
public void setJobId(String jobId) {
this.jobId = jobId;
}
public Date getModifiedTime() {
return modifiedTime;
}
public void setModifiedTime(Date modifiedTime) {
this.modifiedTime = modifiedTime;
}
public String getModifiedUsername() {
return modifiedUsername;
}
public void setModifiedUsername(String modifiedUsername) {
this.modifiedUsername = modifiedUsername;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = Objects.requireNonNull(type);
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
@ -254,4 +201,85 @@ public class Annotation implements ToXContentObject, Writeable {
Objects.equals(modifiedUsername, other.modifiedUsername) &&
Objects.equals(type, other.type);
}
public static class Builder {
private String annotation;
private Date createTime;
private String createUsername;
private Date timestamp;
private Date endTimestamp;
/**
* Unlike most ML classes, this may be <code>null</code> or wildcarded
*/
private String jobId;
private Date modifiedTime;
private String modifiedUsername;
private String type;
public Builder() {}
public Builder(Annotation other) {
Objects.requireNonNull(other);
this.annotation = other.annotation;
this.createTime = new Date(other.createTime.getTime());
this.createUsername = other.createUsername;
this.timestamp = new Date(other.timestamp.getTime());
this.endTimestamp = other.endTimestamp == null ? null : new Date(other.endTimestamp.getTime());
this.jobId = other.jobId;
this.modifiedTime = other.modifiedTime == null ? null : new Date(other.modifiedTime.getTime());
this.modifiedUsername = other.modifiedUsername;
this.type = other.type;
}
public Builder setAnnotation(String annotation) {
this.annotation = Objects.requireNonNull(annotation);
return this;
}
public Builder setCreateTime(Date createTime) {
this.createTime = Objects.requireNonNull(createTime);
return this;
}
public Builder setCreateUsername(String createUsername) {
this.createUsername = Objects.requireNonNull(createUsername);
return this;
}
public Builder setTimestamp(Date timestamp) {
this.timestamp = Objects.requireNonNull(timestamp);
return this;
}
public Builder setEndTimestamp(Date endTimestamp) {
this.endTimestamp = endTimestamp;
return this;
}
public Builder setJobId(String jobId) {
this.jobId = jobId;
return this;
}
public Builder setModifiedTime(Date modifiedTime) {
this.modifiedTime = modifiedTime;
return this;
}
public Builder setModifiedUsername(String modifiedUsername) {
this.modifiedUsername = modifiedUsername;
return this;
}
public Builder setType(String type) {
this.type = Objects.requireNonNull(type);
return this;
}
public Annotation build() {
return new Annotation(
annotation, createTime, createUsername, timestamp, endTimestamp, jobId, modifiedTime, modifiedUsername, type);
}
}
}

View File

@ -113,7 +113,7 @@ public class AnnotationPersisterTests extends ESTestCase {
private Annotation parseAnnotation(BytesReference source) throws IOException {
try (XContentParser parser = createParser(jsonXContent, source)) {
return Annotation.PARSER.parse(parser, null);
return Annotation.PARSER.parse(parser, null).build();
}
}
}

View File

@ -17,7 +17,7 @@ public class AnnotationTests extends AbstractSerializingTestCase<Annotation> {
@Override
protected Annotation doParseInstance(XContentParser parser) {
return Annotation.PARSER.apply(parser, null);
return Annotation.PARSER.apply(parser, null).build();
}
@Override
@ -26,15 +26,17 @@ public class AnnotationTests extends AbstractSerializingTestCase<Annotation> {
}
static Annotation randomAnnotation() {
return new Annotation(randomAlphaOfLengthBetween(100, 1000),
new Date(randomNonNegativeLong()),
randomAlphaOfLengthBetween(5, 20),
new Date(randomNonNegativeLong()),
randomBoolean() ? new Date(randomNonNegativeLong()) : null,
randomBoolean() ? randomAlphaOfLengthBetween(10, 30) : null,
randomBoolean() ? new Date(randomNonNegativeLong()) : null,
randomBoolean() ? randomAlphaOfLengthBetween(5, 20) : null,
randomAlphaOfLengthBetween(10, 15));
return new Annotation.Builder()
.setAnnotation(randomAlphaOfLengthBetween(100, 1000))
.setCreateTime(new Date(randomNonNegativeLong()))
.setCreateUsername(randomAlphaOfLengthBetween(5, 20))
.setTimestamp(new Date(randomNonNegativeLong()))
.setEndTimestamp(randomBoolean() ? new Date(randomNonNegativeLong()) : null)
.setJobId(randomBoolean() ? randomAlphaOfLengthBetween(10, 30) : null)
.setModifiedTime(randomBoolean() ? new Date(randomNonNegativeLong()) : null)
.setModifiedUsername(randomBoolean() ? randomAlphaOfLengthBetween(5, 20) : null)
.setType(randomAlphaOfLengthBetween(10, 15))
.build();
}
@Override
@ -45,7 +47,7 @@ public class AnnotationTests extends AbstractSerializingTestCase<Annotation> {
public void testCopyConstructor() {
for (int i = 0; i < NUMBER_OF_TEST_RUNS; i++) {
Annotation testAnnotation = createTestInstance();
assertThat(testAnnotation, equalTo(new Annotation(testAnnotation)));
assertThat(testAnnotation, equalTo(new Annotation.Builder(testAnnotation).build()));
}
}
}

View File

@ -243,26 +243,27 @@ class DatafeedJob {
private Annotation createDelayedDataAnnotation(Date startTime, Date endTime, String msg) {
Date currentTime = new Date(currentTimeSupplier.get());
return new Annotation(
msg,
currentTime,
XPackUser.NAME,
startTime,
endTime,
jobId,
currentTime,
XPackUser.NAME,
"annotation");
return new Annotation.Builder()
.setAnnotation(msg)
.setCreateTime(currentTime)
.setCreateUsername(XPackUser.NAME)
.setTimestamp(startTime)
.setEndTimestamp(endTime)
.setJobId(jobId)
.setModifiedTime(currentTime)
.setModifiedUsername(XPackUser.NAME)
.setType("annotation")
.build();
}
private Annotation updateAnnotation(Annotation annotation) {
Annotation updatedAnnotation = new Annotation(lastDataCheckAnnotationWithId.v2());
updatedAnnotation.setModifiedUsername(XPackUser.NAME);
updatedAnnotation.setModifiedTime(new Date(currentTimeSupplier.get()));
updatedAnnotation.setAnnotation(annotation.getAnnotation());
updatedAnnotation.setTimestamp(annotation.getTimestamp());
updatedAnnotation.setEndTimestamp(annotation.getEndTimestamp());
return updatedAnnotation;
return new Annotation.Builder(lastDataCheckAnnotationWithId.v2())
.setAnnotation(annotation.getAnnotation())
.setTimestamp(annotation.getTimestamp())
.setEndTimestamp(annotation.getEndTimestamp())
.setModifiedTime(new Date(currentTimeSupplier.get()))
.setModifiedUsername(XPackUser.NAME)
.build();
}
/**

View File

@ -328,16 +328,17 @@ public class AutodetectResultProcessor {
private Annotation createModelSnapshotAnnotation(ModelSnapshot modelSnapshot) {
assert modelSnapshot != null;
Date currentTime = new Date(clock.millis());
return new Annotation(
Messages.getMessage(Messages.JOB_AUDIT_SNAPSHOT_STORED, modelSnapshot.getSnapshotId()),
currentTime,
XPackUser.NAME,
modelSnapshot.getLatestResultTimeStamp(),
modelSnapshot.getLatestResultTimeStamp(),
jobId,
currentTime,
XPackUser.NAME,
"annotation");
return new Annotation.Builder()
.setAnnotation(Messages.getMessage(Messages.JOB_AUDIT_SNAPSHOT_STORED, modelSnapshot.getSnapshotId()))
.setCreateTime(currentTime)
.setCreateUsername(XPackUser.NAME)
.setTimestamp(modelSnapshot.getLatestResultTimeStamp())
.setEndTimestamp(modelSnapshot.getLatestResultTimeStamp())
.setJobId(jobId)
.setModifiedTime(currentTime)
.setModifiedUsername(XPackUser.NAME)
.setType("annotation")
.build();
}
private void processModelSizeStats(ModelSizeStats modelSizeStats) {

View File

@ -272,15 +272,17 @@ public class DatafeedJobTests extends ESTestCase {
10,
XContentElasticsearchExtension.DEFAULT_DATE_PRINTER.print(2000));
Annotation expectedAnnotation = new Annotation(msg,
new Date(currentTime),
XPackUser.NAME,
bucket.getTimestamp(),
new Date((bucket.getEpoch() + bucket.getBucketSpan()) * 1000),
jobId,
new Date(currentTime),
XPackUser.NAME,
"annotation");
Annotation expectedAnnotation = new Annotation.Builder()
.setAnnotation(msg)
.setCreateTime(new Date(currentTime))
.setCreateUsername(XPackUser.NAME)
.setTimestamp(bucket.getTimestamp())
.setEndTimestamp(new Date((bucket.getEpoch() + bucket.getBucketSpan()) * 1000))
.setJobId(jobId)
.setModifiedTime(new Date(currentTime))
.setModifiedUsername(XPackUser.NAME)
.setType("annotation")
.build();
IndexRequest request = new IndexRequest(AnnotationIndex.WRITE_ALIAS_NAME);
try (XContentBuilder xContentBuilder = expectedAnnotation.toXContent(XContentFactory.jsonBuilder(), ToXContent.EMPTY_PARAMS)) {
@ -312,11 +314,11 @@ public class DatafeedJobTests extends ESTestCase {
// What we expect the updated annotation to be indexed as
IndexRequest indexRequest = new IndexRequest(AnnotationIndex.WRITE_ALIAS_NAME);
indexRequest.id(annotationDocId);
Annotation updatedAnnotation = new Annotation(expectedAnnotation);
updatedAnnotation.setAnnotation(msg);
updatedAnnotation.setModifiedTime(new Date(currentTime));
updatedAnnotation.setModifiedUsername(XPackUser.NAME);
updatedAnnotation.setEndTimestamp(new Date((bucket2.getEpoch() + bucket2.getBucketSpan()) * 1000));
Annotation updatedAnnotation = new Annotation.Builder(expectedAnnotation)
.setAnnotation(msg)
.setEndTimestamp(new Date((bucket2.getEpoch() + bucket2.getBucketSpan()) * 1000))
.setModifiedTime(new Date(currentTime))
.build();
try (XContentBuilder xContentBuilder = updatedAnnotation.toXContent(XContentFactory.jsonBuilder(), ToXContent.EMPTY_PARAMS)) {
indexRequest.source(xContentBuilder);
}

View File

@ -684,7 +684,7 @@ public class AutodetectResultProcessorIT extends MlSingleNodeTestCase {
private Annotation parseAnnotation(BytesReference source) throws IOException {
try (XContentParser parser = createParser(jsonXContent, source)) {
return Annotation.PARSER.parse(parser, null);
return Annotation.PARSER.parse(parser, null).build();
}
}

View File

@ -386,16 +386,17 @@ public class AutodetectResultProcessorTests extends ESTestCase {
eq(ModelSnapshot.annotationDocumentId(modelSnapshot)), annotationCaptor.capture(), any());
Annotation annotation = annotationCaptor.getValue();
Annotation expectedAnnotation =
new Annotation(
"Job model snapshot with id [a_snapshot_id] stored",
Date.from(CURRENT_TIME),
XPackUser.NAME,
Date.from(Instant.ofEpochMilli(1000_000_000)),
Date.from(Instant.ofEpochMilli(1000_000_000)),
JOB_ID,
Date.from(CURRENT_TIME),
XPackUser.NAME,
"annotation");
new Annotation.Builder()
.setAnnotation("Job model snapshot with id [a_snapshot_id] stored")
.setCreateTime(Date.from(CURRENT_TIME))
.setCreateUsername(XPackUser.NAME)
.setTimestamp(Date.from(Instant.ofEpochMilli(1000_000_000)))
.setEndTimestamp(Date.from(Instant.ofEpochMilli(1000_000_000)))
.setJobId(JOB_ID)
.setModifiedTime(Date.from(CURRENT_TIME))
.setModifiedUsername(XPackUser.NAME)
.setType("annotation")
.build();
assertThat(annotation, is(equalTo(expectedAnnotation)));
UpdateJobAction.Request expectedJobUpdateRequest = UpdateJobAction.Request.internal(JOB_ID,