All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.elasticsearch.xpack.core.ml.job.config.MlFilter Maven / Gradle / Ivy

/*
 * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
 * or more contributor license agreements. Licensed under the Elastic License
 * 2.0; you may not use this file except in compliance with the Elastic License
 * 2.0.
 */
package org.elasticsearch.xpack.core.ml.job.config;

import org.elasticsearch.Version;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.ParseField;
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.ObjectParser;
import org.elasticsearch.common.xcontent.ToXContentObject;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.xpack.core.ml.job.messages.Messages;
import org.elasticsearch.xpack.core.ml.utils.ExceptionsHelper;
import org.elasticsearch.xpack.core.ml.utils.MlStrings;
import org.elasticsearch.xpack.core.ml.utils.ToXContentParams;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.SortedSet;
import java.util.TreeSet;

public class MlFilter implements ToXContentObject, Writeable {

    /**
     * The max number of items allowed per filter.
     * Limiting the number of items protects users
     * from running into excessive overhead due to
     * filters using too much memory and lookups
     * becoming too expensive.
     */
    private static final int MAX_ITEMS = 10000;

    public static final String DOCUMENT_ID_PREFIX = "filter_";

    public static final String FILTER_TYPE = "filter";

    public static final ParseField TYPE = new ParseField("type");
    public static final ParseField ID = new ParseField("filter_id");
    public static final ParseField DESCRIPTION = new ParseField("description");
    public static final ParseField ITEMS = new ParseField("items");

    // For QueryPage
    public static final ParseField RESULTS_FIELD = new ParseField("filters");

    public static final ObjectParser STRICT_PARSER = createParser(false);
    public static final ObjectParser LENIENT_PARSER = createParser(true);

    private static ObjectParser createParser(boolean ignoreUnknownFields) {
        ObjectParser parser = new ObjectParser<>(TYPE.getPreferredName(), ignoreUnknownFields, Builder::new);

        parser.declareString((builder, s) -> {}, TYPE);
        parser.declareString(Builder::setId, ID);
        parser.declareStringOrNull(Builder::setDescription, DESCRIPTION);
        parser.declareStringArray(Builder::setItems, ITEMS);

        return parser;
    }

    private final String id;
    private final String description;
    private final SortedSet items;

    private MlFilter(String id, String description, SortedSet items) {
        this.id = Objects.requireNonNull(id);
        this.description = description;
        this.items = Objects.requireNonNull(items);
    }

    public MlFilter(StreamInput in) throws IOException {
        id = in.readString();
        if (in.getVersion().onOrAfter(Version.V_6_4_0)) {
            description = in.readOptionalString();
        } else {
            description = null;
        }
        items = new TreeSet<>(Arrays.asList(in.readStringArray()));
    }

    @Override
    public void writeTo(StreamOutput out) throws IOException {
        out.writeString(id);
        if (out.getVersion().onOrAfter(Version.V_6_4_0)) {
            out.writeOptionalString(description);
        }
        out.writeStringArray(items.toArray(new String[items.size()]));
    }

    @Override
    public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
        builder.startObject();
        builder.field(ID.getPreferredName(), id);
        if (description != null) {
            builder.field(DESCRIPTION.getPreferredName(), description);
        }
        builder.field(ITEMS.getPreferredName(), items);
        if (params.paramAsBoolean(ToXContentParams.FOR_INTERNAL_STORAGE, false)) {
            builder.field(TYPE.getPreferredName(), FILTER_TYPE);
        }
        builder.endObject();
        return builder;
    }

    public String getId() {
        return id;
    }

    public String getDescription() {
        return description;
    }

    public SortedSet getItems() {
        return Collections.unmodifiableSortedSet(items);
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        }

        if ((obj instanceof MlFilter) == false) {
            return false;
        }

        MlFilter other = (MlFilter) obj;
        return id.equals(other.id) && Objects.equals(description, other.description) && items.equals(other.items);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, description, items);
    }

    public String documentId() {
        return documentId(id);
    }

    public static String documentId(String filterId) {
        return DOCUMENT_ID_PREFIX + filterId;
    }

    public static Builder builder(String filterId) {
        return new Builder().setId(filterId);
    }

    public static class Builder {

        private String id;
        private String description;
        private SortedSet items = new TreeSet<>();

        private Builder() {}

        public Builder setId(String id) {
            this.id = id;
            return this;
        }

        @Nullable
        public String getId() {
            return id;
        }

        public Builder setDescription(String description) {
            this.description = description;
            return this;
        }

        public Builder setItems(SortedSet items) {
            this.items = items;
            return this;
        }

        public Builder setItems(List items) {
            this.items = new TreeSet<>(items);
            return this;
        }

        public Builder setItems(String... items) {
            setItems(Arrays.asList(items));
            return this;
        }

        public MlFilter build() {
            ExceptionsHelper.requireNonNull(id, MlFilter.ID.getPreferredName());
            ExceptionsHelper.requireNonNull(items, MlFilter.ITEMS.getPreferredName());
            if (MlStrings.isValidId(id) == false) {
                throw ExceptionsHelper.badRequestException(Messages.getMessage(Messages.INVALID_ID, ID.getPreferredName(), id));
            }
            if (items.size() > MAX_ITEMS) {
                throw ExceptionsHelper.badRequestException(Messages.getMessage(Messages.FILTER_CONTAINS_TOO_MANY_ITEMS, id, MAX_ITEMS));
            }
            return new MlFilter(id, description, items);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy