-
Notifications
You must be signed in to change notification settings - Fork 24.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[ML] Add a file structure determination endpoint #33471
Changes from 1 commit
2aca21f
efd2ed7
8440f0f
c6fba6f
8e840a6
344b140
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
package org.elasticsearch.xpack.core.ml.action; | ||
|
||
import org.elasticsearch.action.Action; | ||
import org.elasticsearch.action.ActionRequest; | ||
import org.elasticsearch.action.ActionRequestBuilder; | ||
import org.elasticsearch.action.ActionRequestValidationException; | ||
import org.elasticsearch.action.ActionResponse; | ||
import org.elasticsearch.client.ElasticsearchClient; | ||
import org.elasticsearch.common.ParseField; | ||
import org.elasticsearch.common.bytes.BytesReference; | ||
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.StatusToXContentObject; | ||
import org.elasticsearch.common.xcontent.XContentBuilder; | ||
import org.elasticsearch.rest.RestStatus; | ||
import org.elasticsearch.xpack.core.ml.filestructurefinder.FileStructure; | ||
|
||
import java.io.IOException; | ||
import java.util.Objects; | ||
|
||
import static org.elasticsearch.action.ValidateActions.addValidationError; | ||
|
||
public class FileStructureAction extends Action<FileStructureAction.Response> { | ||
|
||
public static final FileStructureAction INSTANCE = new FileStructureAction(); | ||
public static final String NAME = "cluster:monitor/xpack/ml/filestructure"; | ||
|
||
private FileStructureAction() { | ||
super(NAME); | ||
} | ||
|
||
@Override | ||
public Response newResponse() { | ||
return new Response(); | ||
} | ||
|
||
static class RequestBuilder extends ActionRequestBuilder<Request, Response> { | ||
|
||
RequestBuilder(ElasticsearchClient client, FileStructureAction action) { | ||
super(client, action, new Request()); | ||
} | ||
} | ||
|
||
public static class Response extends ActionResponse implements StatusToXContentObject, Writeable { | ||
|
||
private FileStructure fileStructure; | ||
|
||
public Response(FileStructure fileStructure) { | ||
this.fileStructure = fileStructure; | ||
} | ||
|
||
public Response() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we need this at all, it should not be |
||
} | ||
|
||
public FileStructure getFileStructure() { | ||
return fileStructure; | ||
} | ||
|
||
@Override | ||
public void readFrom(StreamInput in) throws IOException { | ||
super.readFrom(in); | ||
fileStructure = new FileStructure(in); | ||
} | ||
|
||
@Override | ||
public void writeTo(StreamOutput out) throws IOException { | ||
super.writeTo(out); | ||
fileStructure.writeTo(out); | ||
} | ||
|
||
@Override | ||
public RestStatus status() { | ||
return RestStatus.OK; | ||
} | ||
|
||
@Override | ||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { | ||
fileStructure.toXContent(builder, params); | ||
return builder; | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(fileStructure); | ||
} | ||
|
||
@Override | ||
public boolean equals(Object other) { | ||
|
||
if (this == other) { | ||
return true; | ||
} | ||
|
||
if (other == null || getClass() != other.getClass()) { | ||
return false; | ||
} | ||
|
||
FileStructureAction.Response that = (FileStructureAction.Response) other; | ||
return Objects.equals(fileStructure, that.fileStructure); | ||
} | ||
} | ||
|
||
public static class Request extends ActionRequest { | ||
|
||
public static final ParseField LINES_TO_SAMPLE = new ParseField("lines_to_sample"); | ||
|
||
private Integer linesToSample; | ||
private BytesReference sample; | ||
|
||
public Request() { | ||
} | ||
|
||
public Integer getLinesToSample() { | ||
return linesToSample; | ||
} | ||
|
||
public void setLinesToSample(Integer linesToSample) { | ||
this.linesToSample = linesToSample; | ||
} | ||
|
||
public BytesReference getSample() { | ||
return sample; | ||
} | ||
|
||
public void setSample(BytesReference sample) { | ||
this.sample = sample; | ||
} | ||
|
||
@Override | ||
public ActionRequestValidationException validate() { | ||
ActionRequestValidationException validationException = null; | ||
if (linesToSample != null && linesToSample <= 0) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we also check against an upper bound? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the uploaded data contains fewer lines then we just sample all of what's been uploaded. Therefore the number of lines that can be sampled is limited by the size of the ES HTTP receive buffer. One problem with sampling many lines is the time taken to do the analysis. At some point I should probably add the option to limit the maximum time allowed. Some other functionality has this facility, like the Grok ingest processor. But I'd rather do this in a followup PR. |
||
validationException = addValidationError("lines_to_sample must be positive if specified", validationException); | ||
} | ||
if (sample == null) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. may want to verify that |
||
validationException = addValidationError("sample must be specified", validationException); | ||
} | ||
return validationException; | ||
} | ||
|
||
@Override | ||
public void readFrom(StreamInput in) throws IOException { | ||
super.readFrom(in); | ||
linesToSample = in.readOptionalVInt(); | ||
sample = in.readBytesReference(); | ||
} | ||
|
||
@Override | ||
public void writeTo(StreamOutput out) throws IOException { | ||
super.writeTo(out); | ||
out.writeOptionalVInt(linesToSample); | ||
out.writeBytesReference(sample); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(linesToSample, sample); | ||
} | ||
|
||
@Override | ||
public boolean equals(Object other) { | ||
|
||
if (this == other) { | ||
return true; | ||
} | ||
|
||
if (other == null || getClass() != other.getClass()) { | ||
return false; | ||
} | ||
|
||
Request that = (Request) other; | ||
return Objects.equals(this.linesToSample, that.linesToSample) && | ||
Objects.equals(this.sample, that.sample); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
package org.elasticsearch.xpack.core.ml.action; | ||
|
||
import org.elasticsearch.common.bytes.BytesArray; | ||
import org.elasticsearch.test.AbstractStreamableTestCase; | ||
|
||
public class FileStructureActionRequestTests extends AbstractStreamableTestCase<FileStructureAction.Request> { | ||
|
||
@Override | ||
protected FileStructureAction.Request createTestInstance() { | ||
|
||
FileStructureAction.Request request = new FileStructureAction.Request(); | ||
|
||
if (randomBoolean()) { | ||
request.setLinesToSample(randomIntBetween(10, 2000)); | ||
} | ||
request.setSample(new BytesArray(randomByteArrayOfLength(randomIntBetween(1000, 20000)))); | ||
|
||
return request; | ||
} | ||
|
||
@Override | ||
protected FileStructureAction.Request createBlankInstance() { | ||
return new FileStructureAction.Request(); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a note that this is different in
6.x
so make sure to fix compilation problems before backporting.