Skip to content
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

Implement aggregate_metric field mapper #49830

Merged
merged 31 commits into from
Mar 31, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
92ccb70
Implemented aggregate_metric field type for storing pre-computed aggr…
csoulios Dec 4, 2019
3f41428
Addressing code review comments
csoulios Dec 5, 2019
556e086
Moved AggregateMetricFieldMapper to its own module
csoulios Dec 5, 2019
6d50c75
Fix broken doc test
csoulios Dec 11, 2019
527097e
Fixes to address code review comments
csoulios Dec 11, 2019
0eed690
Merge branch 'master' into rollups
csoulios Dec 16, 2019
29a1eb3
Fixes to address code review comments.
csoulios Dec 17, 2019
471f23b
Fix broken integration tests
csoulios Dec 17, 2019
5ef5e84
Added delegate field mappers of NumberFieldType
csoulios Dec 20, 2019
4fb0b1c
Merge branch 'master' into rollups
csoulios Jan 3, 2020
7a1f776
Delegate queries to NumberFieldType fields
csoulios Jan 7, 2020
6ae9c1b
Merge branch 'master' into rollups
csoulios Jan 7, 2020
c8390cd
Style fixes
csoulios Jan 7, 2020
1fb227c
Nit: removed blank line
csoulios Jan 10, 2020
8ba840c
Addressed reviewer comments
csoulios Jan 10, 2020
8f10a26
Fixed NPE issue when "metrics" field is missing
csoulios Jan 10, 2020
dee09e3
Added integration test
csoulios Jan 10, 2020
37f1a4a
Merge branch 'master' into rollups
csoulios Jan 10, 2020
8528f29
Override AggregateDoubleMetricFieldMapper methods
csoulios Jan 13, 2020
0de6269
Merge branch 'feature/aggregate-metrics' into rollups
csoulios Jan 16, 2020
c8849c2
Ensure that a metric field cannot be an array
csoulios Jan 16, 2020
02d53db
Ensure that merging two fields with different
csoulios Jan 16, 2020
f732059
Merge branch 'master' into rollups
csoulios Feb 17, 2020
86a5e6b
Merge branch 'master' into rollups
csoulios Feb 18, 2020
44652c0
Checkstyle
csoulios Feb 18, 2020
de72c40
Fix typo
csoulios Feb 18, 2020
031cd01
Merge branch 'feature/aggregate-metrics' into rollups
csoulios Mar 27, 2020
866a0e1
Applied "spotless"
csoulios Mar 27, 2020
1984398
Fixed broken doc-test after merge
csoulios Mar 27, 2020
dc86339
Added test for nested aggregate_metric field
csoulios Mar 30, 2020
b5e3322
Merge branch 'feature/aggregate-metrics' into rollups
csoulios Mar 30, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -733,6 +733,15 @@ public synchronized boolean isFlattenedAllowed() {
return status.active;
}

/**
* Determine if support for aggregate metric object fields should be enabled.
* <p>
* Aggregate metric fields are available for all license types except {@link OperationMode#MISSING}.
*/
public synchronized boolean isAggregateMetricAllowed() {
return status.active;
}

/**
* Determine if Vectors support should be enabled.
* <p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ public final class XPackField {
public static final String ANALYTICS = "analytics";
/** Name constant for the enrich plugin. */
public static final String ENRICH = "enrich";
/** Name constant for the aggregate_metric plugin. */
public static final String AGGREGATE_METRIC = "aggregate_metric";

private XPackField() {}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ private XPackSettings() {
/** Setting for enabling or disabling vectors. Defaults to true. */
public static final Setting<Boolean> VECTORS_ENABLED = Setting.boolSetting("xpack.vectors.enabled", true, Setting.Property.NodeScope);

/** Setting for enabling or disabling aggregate_metric fields. Defaults to true. */
public static final Setting<Boolean> AGGREGATE_METRIC_ENABLED = Setting.boolSetting("xpack.aggregate_metric.enabled",
csoulios marked this conversation as resolved.
Show resolved Hide resolved
true, Setting.Property.NodeScope);

/*
* SSL settings. These are the settings that are specifically registered for SSL. Many are private as we do not explicitly use them
* but instead parse based on a prefix (eg *.ssl.*)
Expand Down Expand Up @@ -240,6 +244,7 @@ public static List<Setting<?>> getAllSettings() {
settings.add(TRANSFORM_ENABLED);
settings.add(FLATTENED_ENABLED);
settings.add(VECTORS_ENABLED);
settings.add(AGGREGATE_METRIC_ENABLED);
return Collections.unmodifiableList(settings);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,11 @@ public class XPackInfoFeatureAction extends ActionType<XPackInfoFeatureResponse>
public static final XPackInfoFeatureAction SPATIAL = new XPackInfoFeatureAction(XPackField.SPATIAL);
public static final XPackInfoFeatureAction ANALYTICS = new XPackInfoFeatureAction(XPackField.ANALYTICS);
public static final XPackInfoFeatureAction ENRICH = new XPackInfoFeatureAction(XPackField.ENRICH);
public static final XPackInfoFeatureAction AGGREGATE_METRIC = new XPackInfoFeatureAction(XPackField.AGGREGATE_METRIC);

public static final List<XPackInfoFeatureAction> ALL = Arrays.asList(
SECURITY, MONITORING, WATCHER, GRAPH, MACHINE_LEARNING, LOGSTASH, SQL, ROLLUP, INDEX_LIFECYCLE, SNAPSHOT_LIFECYCLE, CCR,
TRANSFORM, FLATTENED, VECTORS, VOTING_ONLY, FROZEN_INDICES, SPATIAL, ANALYTICS, ENRICH
TRANSFORM, FLATTENED, VECTORS, VOTING_ONLY, FROZEN_INDICES, SPATIAL, ANALYTICS, ENRICH, AGGREGATE_METRIC
);

private XPackInfoFeatureAction(String name) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,12 @@ public class XPackUsageFeatureAction extends ActionType<XPackUsageFeatureRespons
public static final XPackUsageFeatureAction FROZEN_INDICES = new XPackUsageFeatureAction(XPackField.FROZEN_INDICES);
public static final XPackUsageFeatureAction SPATIAL = new XPackUsageFeatureAction(XPackField.SPATIAL);
public static final XPackUsageFeatureAction ANALYTICS = new XPackUsageFeatureAction(XPackField.ANALYTICS);
public static final XPackUsageFeatureAction AGGREGATE_METRIC = new XPackUsageFeatureAction(XPackField.AGGREGATE_METRIC);


public static final List<XPackUsageFeatureAction> ALL = Arrays.asList(
SECURITY, MONITORING, WATCHER, GRAPH, MACHINE_LEARNING, LOGSTASH, SQL, ROLLUP, INDEX_LIFECYCLE, SNAPSHOT_LIFECYCLE, CCR,
TRANSFORM, FLATTENED, VECTORS, VOTING_ONLY, FROZEN_INDICES, SPATIAL, ANALYTICS
TRANSFORM, FLATTENED, VECTORS, VOTING_ONLY, FROZEN_INDICES, SPATIAL, ANALYTICS, AGGREGATE_METRIC
);

private XPackUsageFeatureAction(String name) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* 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.aggregatemetric;

import org.elasticsearch.Version;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.xpack.core.XPackFeatureSet;
import org.elasticsearch.xpack.core.XPackField;

import java.io.IOException;
import java.util.Objects;

public class AggregateMetricFeatureSetUsage extends XPackFeatureSet.Usage {
private final int fieldCount;

public AggregateMetricFeatureSetUsage(StreamInput input) throws IOException {
super(input);
this.fieldCount = input.getVersion().onOrAfter(Version.V_8_0_0) ? input.readInt() : 0;
}

public AggregateMetricFeatureSetUsage(boolean available, boolean enabled, int fieldCount) {
super(XPackField.AGGREGATE_METRIC, available, enabled);
this.fieldCount = fieldCount;
}

int fieldCount() {
return fieldCount;
}

@Override
public void writeTo(StreamOutput out) throws IOException {
super.writeTo(out);
if (out.getVersion().onOrAfter(Version.V_8_0_0)) {
out.writeInt(fieldCount);
}
}

@Override
protected void innerXContent(XContentBuilder builder, Params params) throws IOException {
super.innerXContent(builder, params);
builder.field("field_count", fieldCount);
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AggregateMetricFeatureSetUsage that = (AggregateMetricFeatureSetUsage) o;
return available == that.available && enabled == that.enabled && fieldCount == that.fieldCount;
}

@Override
public int hashCode() {
return Objects.hash(available, enabled, fieldCount);
}
}
24 changes: 24 additions & 0 deletions x-pack/plugin/mapper-aggregate-metric/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* 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.
*/

evaluationDependsOn(xpackModule('core'))

apply plugin: 'elasticsearch.esplugin'

esplugin {
name 'x-pack-aggregate-metric'
description 'Module for the aggregate_metric field type, which allows pre-aggregated fields to be stored a single field.'
classname 'org.elasticsearch.xpack.aggregatemetric.AggregateMetricMapperPlugin'
extendedPlugins = ['x-pack-core']
}
archivesBaseName = 'x-pack-aggregate-metric'

dependencies {
compileOnly project(path: xpackModule('core'), configuration: 'default')
testCompile project(path: xpackModule('core'), configuration: 'testArtifacts')
}

integTest.enabled = false
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* 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.aggregatemetric;

import org.elasticsearch.action.support.ActionFilters;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.license.XPackLicenseState;
import org.elasticsearch.transport.TransportService;
import org.elasticsearch.xpack.core.XPackField;
import org.elasticsearch.xpack.core.XPackSettings;
import org.elasticsearch.xpack.core.action.XPackInfoFeatureAction;
import org.elasticsearch.xpack.core.action.XPackInfoFeatureTransportAction;

public class AggregateMetricInfoTransportAction extends XPackInfoFeatureTransportAction {

private final boolean enabled;
private final XPackLicenseState licenseState;

@Inject
public AggregateMetricInfoTransportAction(TransportService transportService, ActionFilters actionFilters,
Settings settings, XPackLicenseState licenseState) {
super(XPackInfoFeatureAction.AGGREGATE_METRIC.name(), transportService, actionFilters);
this.enabled = XPackSettings.AGGREGATE_METRIC_ENABLED.get(settings);
this.licenseState = licenseState;
}

@Override
public String name() {
return XPackField.AGGREGATE_METRIC;
}

@Override
public boolean available() {
return licenseState.isAggregateMetricAllowed();
}

@Override
public boolean enabled() {
return enabled;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* 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.aggregatemetric;

import org.elasticsearch.action.ActionRequest;
import org.elasticsearch.action.ActionResponse;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.mapper.Mapper;
import org.elasticsearch.plugins.ActionPlugin;
import org.elasticsearch.plugins.MapperPlugin;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.xpack.aggregatemetric.mapper.AggregateMetricFieldMapper;
import org.elasticsearch.xpack.core.XPackSettings;
import org.elasticsearch.xpack.core.action.XPackInfoFeatureAction;
import org.elasticsearch.xpack.core.action.XPackUsageFeatureAction;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

import static java.util.Collections.emptyMap;
import static java.util.Collections.singletonMap;

public class AggregateMetricMapperPlugin extends Plugin implements MapperPlugin, ActionPlugin {

protected final boolean enabled;

public AggregateMetricMapperPlugin(Settings settings) {
this.enabled = XPackSettings.AGGREGATE_METRIC_ENABLED.get(settings);
}

@Override
public Map<String, Mapper.TypeParser> getMappers() {
if (enabled == false) {
return emptyMap();
}
return singletonMap(AggregateMetricFieldMapper.CONTENT_TYPE, new AggregateMetricFieldMapper.TypeParser());
}

@Override
public List<ActionHandler<? extends ActionRequest, ? extends ActionResponse>> getActions() {
return Arrays.asList(
new ActionHandler<>(XPackUsageFeatureAction.AGGREGATE_METRIC, AggregateMetricUsageTransportAction.class),
new ActionHandler<>(XPackInfoFeatureAction.AGGREGATE_METRIC, AggregateMetricInfoTransportAction.class));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* 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.aggregatemetric;

import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.support.ActionFilters;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.metadata.MappingMetaData;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.license.XPackLicenseState;
import org.elasticsearch.protocol.xpack.XPackUsageRequest;
import org.elasticsearch.tasks.Task;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportService;
import org.elasticsearch.xpack.aggregatemetric.mapper.AggregateMetricFieldMapper;
import org.elasticsearch.xpack.core.XPackSettings;
import org.elasticsearch.xpack.core.action.XPackUsageFeatureAction;
import org.elasticsearch.xpack.core.action.XPackUsageFeatureResponse;
import org.elasticsearch.xpack.core.action.XPackUsageFeatureTransportAction;
import org.elasticsearch.xpack.core.aggregatemetric.AggregateMetricFeatureSetUsage;

import java.util.Map;

public class AggregateMetricUsageTransportAction extends XPackUsageFeatureTransportAction {

private final Settings settings;
private final XPackLicenseState licenseState;

@Inject
public AggregateMetricUsageTransportAction(TransportService transportService, ClusterService clusterService, ThreadPool threadPool,
ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver,
Settings settings, XPackLicenseState licenseState) {
super(XPackUsageFeatureAction.AGGREGATE_METRIC.name(), transportService, clusterService,
threadPool, actionFilters, indexNameExpressionResolver);
this.settings = settings;
this.licenseState = licenseState;
}

@Override
protected void masterOperation(Task task, XPackUsageRequest request, ClusterState state,
ActionListener<XPackUsageFeatureResponse> listener) {
boolean allowed = licenseState.isAggregateMetricAllowed();
boolean enabled = XPackSettings.AGGREGATE_METRIC_ENABLED.get(settings);
int fieldCount = 0;

if (allowed && enabled && state != null) {
for (IndexMetaData indexMetaData : state.metaData()) {
MappingMetaData mappingMetaData = indexMetaData.mapping();

if (mappingMetaData != null) {
Map<String, Object> mappings = mappingMetaData.getSourceAsMap();

if (mappings.containsKey("properties")) {
@SuppressWarnings("unchecked")
Map<String, Map<String, Object>> fieldMappings = (Map<String, Map<String, Object>>) mappings.get("properties");

for (Map<String, Object> fieldMapping : fieldMappings.values()) {
String fieldType = (String) fieldMapping.get("type");
if (fieldType != null && fieldType.equals(AggregateMetricFieldMapper.CONTENT_TYPE)) {
fieldCount++;
}
}
}
}
}
}

AggregateMetricFeatureSetUsage usage = new AggregateMetricFeatureSetUsage(allowed, enabled, fieldCount);
listener.onResponse(new XPackUsageFeatureResponse(usage));
}
}
Loading