Skip to content

Commit eb44fe6

Browse files
committed
[ML] Add ML result classes to protocol library (#32587)
This commit adds the ML results classes to the X-Pack protocol library used by the high level REST client. (Other commits will add the config classes and stats classes.) These classes: - Are publically immutable - Are privately mutable - this is perhaps not as nice as the config classes, but to do otherwise would require adding builders and the corresponding server-side classes that the old transport client used don't have builders - Have little/no validation of field values beyond null checks - Are convertible to and from X-Content, but NOT wire transportable - Have lenient parsers to maximize compatibility across versions - Have the same class names and getter names as the corresponding classes in X-Pack core to ease migration for transport client users - Don't reproduce all the methods that do calculations or transformations that the the corresponding classes in X-Pack core have
1 parent 4ade361 commit eb44fe6

17 files changed

+2752
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,292 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.elasticsearch.protocol.xpack.ml.job.results;
20+
21+
import org.elasticsearch.common.ParseField;
22+
import org.elasticsearch.common.xcontent.ObjectParser;
23+
import org.elasticsearch.common.xcontent.ToXContentObject;
24+
import org.elasticsearch.common.xcontent.XContentBuilder;
25+
26+
import java.io.IOException;
27+
import java.util.Collections;
28+
import java.util.List;
29+
import java.util.Objects;
30+
31+
/**
32+
* Anomaly Cause POJO.
33+
* Used as a nested level inside population anomaly records.
34+
*/
35+
public class AnomalyCause implements ToXContentObject {
36+
37+
public static final ParseField ANOMALY_CAUSE = new ParseField("anomaly_cause");
38+
39+
/**
40+
* Result fields
41+
*/
42+
public static final ParseField PROBABILITY = new ParseField("probability");
43+
public static final ParseField OVER_FIELD_NAME = new ParseField("over_field_name");
44+
public static final ParseField OVER_FIELD_VALUE = new ParseField("over_field_value");
45+
public static final ParseField BY_FIELD_NAME = new ParseField("by_field_name");
46+
public static final ParseField BY_FIELD_VALUE = new ParseField("by_field_value");
47+
public static final ParseField CORRELATED_BY_FIELD_VALUE = new ParseField("correlated_by_field_value");
48+
public static final ParseField PARTITION_FIELD_NAME = new ParseField("partition_field_name");
49+
public static final ParseField PARTITION_FIELD_VALUE = new ParseField("partition_field_value");
50+
public static final ParseField FUNCTION = new ParseField("function");
51+
public static final ParseField FUNCTION_DESCRIPTION = new ParseField("function_description");
52+
public static final ParseField TYPICAL = new ParseField("typical");
53+
public static final ParseField ACTUAL = new ParseField("actual");
54+
public static final ParseField INFLUENCERS = new ParseField("influencers");
55+
56+
/**
57+
* Metric Results
58+
*/
59+
public static final ParseField FIELD_NAME = new ParseField("field_name");
60+
61+
public static final ObjectParser<AnomalyCause, Void> PARSER =
62+
new ObjectParser<>(ANOMALY_CAUSE.getPreferredName(), true, AnomalyCause::new);
63+
64+
static {
65+
PARSER.declareDouble(AnomalyCause::setProbability, PROBABILITY);
66+
PARSER.declareString(AnomalyCause::setByFieldName, BY_FIELD_NAME);
67+
PARSER.declareString(AnomalyCause::setByFieldValue, BY_FIELD_VALUE);
68+
PARSER.declareString(AnomalyCause::setCorrelatedByFieldValue, CORRELATED_BY_FIELD_VALUE);
69+
PARSER.declareString(AnomalyCause::setPartitionFieldName, PARTITION_FIELD_NAME);
70+
PARSER.declareString(AnomalyCause::setPartitionFieldValue, PARTITION_FIELD_VALUE);
71+
PARSER.declareString(AnomalyCause::setFunction, FUNCTION);
72+
PARSER.declareString(AnomalyCause::setFunctionDescription, FUNCTION_DESCRIPTION);
73+
PARSER.declareDoubleArray(AnomalyCause::setTypical, TYPICAL);
74+
PARSER.declareDoubleArray(AnomalyCause::setActual, ACTUAL);
75+
PARSER.declareString(AnomalyCause::setFieldName, FIELD_NAME);
76+
PARSER.declareString(AnomalyCause::setOverFieldName, OVER_FIELD_NAME);
77+
PARSER.declareString(AnomalyCause::setOverFieldValue, OVER_FIELD_VALUE);
78+
PARSER.declareObjectArray(AnomalyCause::setInfluencers, Influence.PARSER, INFLUENCERS);
79+
}
80+
81+
private double probability;
82+
private String byFieldName;
83+
private String byFieldValue;
84+
private String correlatedByFieldValue;
85+
private String partitionFieldName;
86+
private String partitionFieldValue;
87+
private String function;
88+
private String functionDescription;
89+
private List<Double> typical;
90+
private List<Double> actual;
91+
private String fieldName;
92+
private String overFieldName;
93+
private String overFieldValue;
94+
95+
private List<Influence> influencers;
96+
97+
AnomalyCause() {
98+
}
99+
100+
@Override
101+
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
102+
builder.startObject();
103+
builder.field(PROBABILITY.getPreferredName(), probability);
104+
if (byFieldName != null) {
105+
builder.field(BY_FIELD_NAME.getPreferredName(), byFieldName);
106+
}
107+
if (byFieldValue != null) {
108+
builder.field(BY_FIELD_VALUE.getPreferredName(), byFieldValue);
109+
}
110+
if (correlatedByFieldValue != null) {
111+
builder.field(CORRELATED_BY_FIELD_VALUE.getPreferredName(), correlatedByFieldValue);
112+
}
113+
if (partitionFieldName != null) {
114+
builder.field(PARTITION_FIELD_NAME.getPreferredName(), partitionFieldName);
115+
}
116+
if (partitionFieldValue != null) {
117+
builder.field(PARTITION_FIELD_VALUE.getPreferredName(), partitionFieldValue);
118+
}
119+
if (function != null) {
120+
builder.field(FUNCTION.getPreferredName(), function);
121+
}
122+
if (functionDescription != null) {
123+
builder.field(FUNCTION_DESCRIPTION.getPreferredName(), functionDescription);
124+
}
125+
if (typical != null) {
126+
builder.field(TYPICAL.getPreferredName(), typical);
127+
}
128+
if (actual != null) {
129+
builder.field(ACTUAL.getPreferredName(), actual);
130+
}
131+
if (fieldName != null) {
132+
builder.field(FIELD_NAME.getPreferredName(), fieldName);
133+
}
134+
if (overFieldName != null) {
135+
builder.field(OVER_FIELD_NAME.getPreferredName(), overFieldName);
136+
}
137+
if (overFieldValue != null) {
138+
builder.field(OVER_FIELD_VALUE.getPreferredName(), overFieldValue);
139+
}
140+
if (influencers != null) {
141+
builder.field(INFLUENCERS.getPreferredName(), influencers);
142+
}
143+
builder.endObject();
144+
return builder;
145+
}
146+
147+
public double getProbability() {
148+
return probability;
149+
}
150+
151+
void setProbability(double value) {
152+
probability = value;
153+
}
154+
155+
public String getByFieldName() {
156+
return byFieldName;
157+
}
158+
159+
void setByFieldName(String value) {
160+
byFieldName = value;
161+
}
162+
163+
public String getByFieldValue() {
164+
return byFieldValue;
165+
}
166+
167+
void setByFieldValue(String value) {
168+
byFieldValue = value;
169+
}
170+
171+
public String getCorrelatedByFieldValue() {
172+
return correlatedByFieldValue;
173+
}
174+
175+
void setCorrelatedByFieldValue(String value) {
176+
correlatedByFieldValue = value;
177+
}
178+
179+
public String getPartitionFieldName() {
180+
return partitionFieldName;
181+
}
182+
183+
void setPartitionFieldName(String field) {
184+
partitionFieldName = field;
185+
}
186+
187+
public String getPartitionFieldValue() {
188+
return partitionFieldValue;
189+
}
190+
191+
void setPartitionFieldValue(String value) {
192+
partitionFieldValue = value;
193+
}
194+
195+
public String getFunction() {
196+
return function;
197+
}
198+
199+
void setFunction(String name) {
200+
function = name;
201+
}
202+
203+
public String getFunctionDescription() {
204+
return functionDescription;
205+
}
206+
207+
void setFunctionDescription(String functionDescription) {
208+
this.functionDescription = functionDescription;
209+
}
210+
211+
public List<Double> getTypical() {
212+
return typical;
213+
}
214+
215+
void setTypical(List<Double> typical) {
216+
this.typical = Collections.unmodifiableList(typical);
217+
}
218+
219+
public List<Double> getActual() {
220+
return actual;
221+
}
222+
223+
void setActual(List<Double> actual) {
224+
this.actual = Collections.unmodifiableList(actual);
225+
}
226+
227+
public String getFieldName() {
228+
return fieldName;
229+
}
230+
231+
void setFieldName(String field) {
232+
fieldName = field;
233+
}
234+
235+
public String getOverFieldName() {
236+
return overFieldName;
237+
}
238+
239+
void setOverFieldName(String name) {
240+
overFieldName = name;
241+
}
242+
243+
public String getOverFieldValue() {
244+
return overFieldValue;
245+
}
246+
247+
void setOverFieldValue(String value) {
248+
overFieldValue = value;
249+
}
250+
251+
public List<Influence> getInfluencers() {
252+
return influencers;
253+
}
254+
255+
void setInfluencers(List<Influence> influencers) {
256+
this.influencers = Collections.unmodifiableList(influencers);
257+
}
258+
259+
@Override
260+
public int hashCode() {
261+
return Objects.hash(probability, actual, typical, byFieldName, byFieldValue, correlatedByFieldValue, fieldName, function,
262+
functionDescription, overFieldName, overFieldValue, partitionFieldName, partitionFieldValue, influencers);
263+
}
264+
265+
@Override
266+
public boolean equals(Object other) {
267+
if (this == other) {
268+
return true;
269+
}
270+
271+
if (other == null || getClass() != other.getClass()) {
272+
return false;
273+
}
274+
275+
AnomalyCause that = (AnomalyCause)other;
276+
277+
return this.probability == that.probability &&
278+
Objects.equals(this.typical, that.typical) &&
279+
Objects.equals(this.actual, that.actual) &&
280+
Objects.equals(this.function, that.function) &&
281+
Objects.equals(this.functionDescription, that.functionDescription) &&
282+
Objects.equals(this.fieldName, that.fieldName) &&
283+
Objects.equals(this.byFieldName, that.byFieldName) &&
284+
Objects.equals(this.byFieldValue, that.byFieldValue) &&
285+
Objects.equals(this.correlatedByFieldValue, that.correlatedByFieldValue) &&
286+
Objects.equals(this.partitionFieldName, that.partitionFieldName) &&
287+
Objects.equals(this.partitionFieldValue, that.partitionFieldValue) &&
288+
Objects.equals(this.overFieldName, that.overFieldName) &&
289+
Objects.equals(this.overFieldValue, that.overFieldValue) &&
290+
Objects.equals(this.influencers, that.influencers);
291+
}
292+
}

0 commit comments

Comments
 (0)