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,41 +30,38 @@ 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,
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);
@ -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,