|
@@ -6,6 +6,7 @@
|
|
|
|
|
|
package org.elasticsearch.xpack.core.dataframe.transforms;
|
|
|
|
|
|
+import org.elasticsearch.Version;
|
|
|
import org.elasticsearch.cluster.AbstractDiffable;
|
|
|
import org.elasticsearch.common.Nullable;
|
|
|
import org.elasticsearch.common.ParseField;
|
|
@@ -14,6 +15,7 @@ import org.elasticsearch.common.io.stream.StreamInput;
|
|
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
|
|
import org.elasticsearch.common.io.stream.Writeable;
|
|
|
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
|
|
|
+import org.elasticsearch.common.xcontent.ObjectParser;
|
|
|
import org.elasticsearch.common.xcontent.ToXContentObject;
|
|
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
|
|
import org.elasticsearch.common.xcontent.XContentParser;
|
|
@@ -21,8 +23,10 @@ import org.elasticsearch.xpack.core.dataframe.DataFrameField;
|
|
|
import org.elasticsearch.xpack.core.dataframe.DataFrameMessages;
|
|
|
import org.elasticsearch.xpack.core.dataframe.transforms.pivot.PivotConfig;
|
|
|
import org.elasticsearch.xpack.core.dataframe.utils.ExceptionsHelper;
|
|
|
+import org.elasticsearch.xpack.core.dataframe.utils.TimeUtils;
|
|
|
|
|
|
import java.io.IOException;
|
|
|
+import java.time.Instant;
|
|
|
import java.util.Collections;
|
|
|
import java.util.Map;
|
|
|
import java.util.Objects;
|
|
@@ -42,6 +46,8 @@ public class DataFrameTransformConfig extends AbstractDiffable<DataFrameTransfor
|
|
|
public static final ParseField PIVOT_TRANSFORM = new ParseField("pivot");
|
|
|
|
|
|
public static final ParseField DESCRIPTION = new ParseField("description");
|
|
|
+ public static final ParseField VERSION = new ParseField("version");
|
|
|
+ public static final ParseField CREATE_TIME = new ParseField("create_time");
|
|
|
private static final ConstructingObjectParser<DataFrameTransformConfig, String> STRICT_PARSER = createParser(false);
|
|
|
private static final ConstructingObjectParser<DataFrameTransformConfig, String> LENIENT_PARSER = createParser(true);
|
|
|
private static final int MAX_DESCRIPTION_LENGTH = 1_000;
|
|
@@ -53,9 +59,17 @@ public class DataFrameTransformConfig extends AbstractDiffable<DataFrameTransfor
|
|
|
// headers store the user context from the creating user, which allows us to run the transform as this user
|
|
|
// the header only contains name, groups and other context but no authorization keys
|
|
|
private Map<String, String> headers;
|
|
|
+ private Version transformVersion;
|
|
|
+ private Instant createTime;
|
|
|
|
|
|
private final PivotConfig pivotConfig;
|
|
|
|
|
|
+ private static void validateStrictParsingParams(Object arg, String parameterName) {
|
|
|
+ if (arg != null) {
|
|
|
+ throw new IllegalArgumentException("Found [" + parameterName + "], not allowed for strict parsing");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
private static ConstructingObjectParser<DataFrameTransformConfig, String> createParser(boolean lenient) {
|
|
|
ConstructingObjectParser<DataFrameTransformConfig, String> parser = new ConstructingObjectParser<>(NAME, lenient,
|
|
|
(args, optionalId) -> {
|
|
@@ -74,9 +88,11 @@ public class DataFrameTransformConfig extends AbstractDiffable<DataFrameTransfor
|
|
|
|
|
|
// ignored, only for internal storage: String docType = (String) args[3];
|
|
|
|
|
|
- // on strict parsing do not allow injection of headers
|
|
|
- if (lenient == false && args[4] != null) {
|
|
|
- throw new IllegalArgumentException("Found [headers], not allowed for strict parsing");
|
|
|
+ // on strict parsing do not allow injection of headers, transform version, or create time
|
|
|
+ if (lenient == false) {
|
|
|
+ validateStrictParsingParams(args[4], HEADERS.getPreferredName());
|
|
|
+ validateStrictParsingParams(args[7], CREATE_TIME.getPreferredName());
|
|
|
+ validateStrictParsingParams(args[8], VERSION.getPreferredName());
|
|
|
}
|
|
|
|
|
|
@SuppressWarnings("unchecked")
|
|
@@ -84,7 +100,14 @@ public class DataFrameTransformConfig extends AbstractDiffable<DataFrameTransfor
|
|
|
|
|
|
PivotConfig pivotConfig = (PivotConfig) args[5];
|
|
|
String description = (String)args[6];
|
|
|
- return new DataFrameTransformConfig(id, source, dest, headers, pivotConfig, description);
|
|
|
+ return new DataFrameTransformConfig(id,
|
|
|
+ source,
|
|
|
+ dest,
|
|
|
+ headers,
|
|
|
+ pivotConfig,
|
|
|
+ description,
|
|
|
+ (Instant)args[7],
|
|
|
+ (String)args[8]);
|
|
|
});
|
|
|
|
|
|
parser.declareString(optionalConstructorArg(), DataFrameField.ID);
|
|
@@ -95,7 +118,9 @@ public class DataFrameTransformConfig extends AbstractDiffable<DataFrameTransfor
|
|
|
parser.declareObject(optionalConstructorArg(), (p, c) -> p.mapStrings(), HEADERS);
|
|
|
parser.declareObject(optionalConstructorArg(), (p, c) -> PivotConfig.fromXContent(p, lenient), PIVOT_TRANSFORM);
|
|
|
parser.declareString(optionalConstructorArg(), DESCRIPTION);
|
|
|
-
|
|
|
+ parser.declareField(optionalConstructorArg(),
|
|
|
+ p -> TimeUtils.parseTimeFieldToInstant(p, CREATE_TIME.getPreferredName()), CREATE_TIME, ObjectParser.ValueType.VALUE);
|
|
|
+ parser.declareString(optionalConstructorArg(), VERSION);
|
|
|
return parser;
|
|
|
}
|
|
|
|
|
@@ -103,12 +128,14 @@ public class DataFrameTransformConfig extends AbstractDiffable<DataFrameTransfor
|
|
|
return NAME + "-" + transformId;
|
|
|
}
|
|
|
|
|
|
- public DataFrameTransformConfig(final String id,
|
|
|
- final SourceConfig source,
|
|
|
- final DestConfig dest,
|
|
|
- final Map<String, String> headers,
|
|
|
- final PivotConfig pivotConfig,
|
|
|
- final String description) {
|
|
|
+ DataFrameTransformConfig(final String id,
|
|
|
+ final SourceConfig source,
|
|
|
+ final DestConfig dest,
|
|
|
+ final Map<String, String> headers,
|
|
|
+ final PivotConfig pivotConfig,
|
|
|
+ final String description,
|
|
|
+ final Instant createTime,
|
|
|
+ final String version){
|
|
|
this.id = ExceptionsHelper.requireNonNull(id, DataFrameField.ID.getPreferredName());
|
|
|
this.source = ExceptionsHelper.requireNonNull(source, DataFrameField.SOURCE.getPreferredName());
|
|
|
this.dest = ExceptionsHelper.requireNonNull(dest, DataFrameField.DESTINATION.getPreferredName());
|
|
@@ -123,6 +150,17 @@ public class DataFrameTransformConfig extends AbstractDiffable<DataFrameTransfor
|
|
|
if (this.description != null && this.description.length() > MAX_DESCRIPTION_LENGTH) {
|
|
|
throw new IllegalArgumentException("[description] must be less than 1000 characters in length.");
|
|
|
}
|
|
|
+ this.createTime = createTime == null ? null : Instant.ofEpochMilli(createTime.toEpochMilli());
|
|
|
+ this.transformVersion = version == null ? null : Version.fromString(version);
|
|
|
+ }
|
|
|
+
|
|
|
+ public DataFrameTransformConfig(final String id,
|
|
|
+ final SourceConfig source,
|
|
|
+ final DestConfig dest,
|
|
|
+ final Map<String, String> headers,
|
|
|
+ final PivotConfig pivotConfig,
|
|
|
+ final String description) {
|
|
|
+ this(id, source, dest, headers, pivotConfig, description, null, null);
|
|
|
}
|
|
|
|
|
|
public DataFrameTransformConfig(final StreamInput in) throws IOException {
|
|
@@ -132,6 +170,13 @@ public class DataFrameTransformConfig extends AbstractDiffable<DataFrameTransfor
|
|
|
setHeaders(in.readMap(StreamInput::readString, StreamInput::readString));
|
|
|
pivotConfig = in.readOptionalWriteable(PivotConfig::new);
|
|
|
description = in.readOptionalString();
|
|
|
+ if (in.getVersion().onOrAfter(Version.V_7_3_0)) {
|
|
|
+ createTime = in.readOptionalInstant();
|
|
|
+ transformVersion = in.readBoolean() ? Version.readVersion(in) : null;
|
|
|
+ } else {
|
|
|
+ createTime = null;
|
|
|
+ transformVersion = null;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
public String getId() {
|
|
@@ -150,8 +195,28 @@ public class DataFrameTransformConfig extends AbstractDiffable<DataFrameTransfor
|
|
|
return headers;
|
|
|
}
|
|
|
|
|
|
- public void setHeaders(Map<String, String> headers) {
|
|
|
+ public DataFrameTransformConfig setHeaders(Map<String, String> headers) {
|
|
|
this.headers = headers;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Version getVersion() {
|
|
|
+ return transformVersion;
|
|
|
+ }
|
|
|
+
|
|
|
+ public DataFrameTransformConfig setVersion(Version transformVersion) {
|
|
|
+ this.transformVersion = transformVersion;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Instant getCreateTime() {
|
|
|
+ return createTime;
|
|
|
+ }
|
|
|
+
|
|
|
+ public DataFrameTransformConfig setCreateTime(Instant createTime) {
|
|
|
+ ExceptionsHelper.requireNonNull(createTime, CREATE_TIME.getPreferredName());
|
|
|
+ this.createTime = Instant.ofEpochMilli(createTime.toEpochMilli());
|
|
|
+ return this;
|
|
|
}
|
|
|
|
|
|
public PivotConfig getPivotConfig() {
|
|
@@ -179,6 +244,15 @@ public class DataFrameTransformConfig extends AbstractDiffable<DataFrameTransfor
|
|
|
out.writeMap(headers, StreamOutput::writeString, StreamOutput::writeString);
|
|
|
out.writeOptionalWriteable(pivotConfig);
|
|
|
out.writeOptionalString(description);
|
|
|
+ if (out.getVersion().onOrAfter(Version.V_7_3_0)) {
|
|
|
+ out.writeOptionalInstant(createTime);
|
|
|
+ if (transformVersion != null) {
|
|
|
+ out.writeBoolean(true);
|
|
|
+ Version.writeVersion(transformVersion, out);
|
|
|
+ } else {
|
|
|
+ out.writeBoolean(false);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -199,6 +273,12 @@ public class DataFrameTransformConfig extends AbstractDiffable<DataFrameTransfor
|
|
|
if (description != null) {
|
|
|
builder.field(DESCRIPTION.getPreferredName(), description);
|
|
|
}
|
|
|
+ if (transformVersion != null) {
|
|
|
+ builder.field(VERSION.getPreferredName(), transformVersion);
|
|
|
+ }
|
|
|
+ if (createTime != null) {
|
|
|
+ builder.timeField(CREATE_TIME.getPreferredName(), CREATE_TIME.getPreferredName() + "_string", createTime.toEpochMilli());
|
|
|
+ }
|
|
|
builder.endObject();
|
|
|
return builder;
|
|
|
}
|
|
@@ -220,12 +300,14 @@ public class DataFrameTransformConfig extends AbstractDiffable<DataFrameTransfor
|
|
|
&& Objects.equals(this.dest, that.dest)
|
|
|
&& Objects.equals(this.headers, that.headers)
|
|
|
&& Objects.equals(this.pivotConfig, that.pivotConfig)
|
|
|
- && Objects.equals(this.description, that.description);
|
|
|
+ && Objects.equals(this.description, that.description)
|
|
|
+ && Objects.equals(this.createTime, that.createTime)
|
|
|
+ && Objects.equals(this.transformVersion, that.transformVersion);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public int hashCode(){
|
|
|
- return Objects.hash(id, source, dest, headers, pivotConfig, description);
|
|
|
+ return Objects.hash(id, source, dest, headers, pivotConfig, description, createTime, transformVersion);
|
|
|
}
|
|
|
|
|
|
@Override
|