Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
@@ -0,0 +1 @@
9260000,9250001
2 changes: 1 addition & 1 deletion server/src/main/resources/transport/upper_bounds/9.3.csv
Original file line number Diff line number Diff line change
@@ -1 +1 @@
initial_9.3.0,9250000
get_inference_fields_action_as_indices_action,9250001
1 change: 1 addition & 0 deletions server/src/main/resources/transport/upper_bounds/9.4.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
get_inference_fields_action_as_indices_action,9260000
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.elasticsearch.action.ActionRequestValidationException;
import org.elasticsearch.action.ActionResponse;
import org.elasticsearch.action.ActionType;
import org.elasticsearch.action.IndicesRequest;
import org.elasticsearch.action.RemoteClusterActionType;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.cluster.metadata.IndexMetadata;
Expand All @@ -24,11 +25,11 @@
import org.elasticsearch.inference.InferenceResults;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static org.elasticsearch.action.ValidateActions.addValidationError;

Expand All @@ -42,31 +43,38 @@
* fields can be gathered more directly using {@link IndexMetadata#getMatchingInferenceFields}.
* </p>
*/
public class GetInferenceFieldsAction extends ActionType<GetInferenceFieldsAction.Response> {
public static final GetInferenceFieldsAction INSTANCE = new GetInferenceFieldsAction();
public class GetInferenceFieldsInternalAction extends ActionType<GetInferenceFieldsInternalAction.Response> {
public static final GetInferenceFieldsInternalAction INSTANCE = new GetInferenceFieldsInternalAction();
public static final RemoteClusterActionType<Response> REMOTE_TYPE = new RemoteClusterActionType<>(INSTANCE.name(), Response::new);

// This is a defunct transport version for when GetInferenceFieldsInternalAction was an internal cluster action. This was the case only
// for 9.3.0 development builds, so there should be no real-world deployments using GetInferenceFieldsInternalAction as an internal
// cluster action. Therefore, this transport version can be disregarded.
public static final TransportVersion GET_INFERENCE_FIELDS_ACTION_TV = TransportVersion.fromName("get_inference_fields_action");

public static final String NAME = "cluster:internal/xpack/inference/fields/get";
public static final TransportVersion GET_INFERENCE_FIELDS_ACTION_AS_INDICES_ACTION_TV = TransportVersion.fromName(
"get_inference_fields_action_as_indices_action"
);

public GetInferenceFieldsAction() {
public static final String NAME = "indices:admin/inference/fields/get";

public GetInferenceFieldsInternalAction() {
super(NAME);
}

public static class Request extends ActionRequest {
private final Set<String> indices;
public static class Request extends ActionRequest implements IndicesRequest.Replaceable {
private String[] indices;
private final Map<String, Float> fields;
private final boolean resolveWildcards;
private final boolean useDefaultFields;
private final String query;
private final IndicesOptions indicesOptions;

/**
* An overload of {@link #Request(Set, Map, boolean, boolean, String, IndicesOptions)} that uses {@link IndicesOptions#DEFAULT}
* An overload of {@link #Request(String[], Map, boolean, boolean, String, IndicesOptions)} that uses {@link IndicesOptions#DEFAULT}
*/
public Request(
Set<String> indices,
String[] indices,
Map<String, Float> fields,
boolean resolveWildcards,
boolean useDefaultFields,
Expand Down Expand Up @@ -97,7 +105,7 @@ public Request(
* @param indicesOptions The {@link IndicesOptions} to use when resolving indices.
*/
public Request(
Set<String> indices,
String[] indices,
Map<String, Float> fields,
boolean resolveWildcards,
boolean useDefaultFields,
Expand All @@ -114,7 +122,7 @@ public Request(

public Request(StreamInput in) throws IOException {
super(in);
this.indices = in.readCollectionAsSet(StreamInput::readString);
this.indices = in.readStringArray();
this.fields = in.readMap(StreamInput::readFloat);
this.resolveWildcards = in.readBoolean();
this.useDefaultFields = in.readBoolean();
Expand All @@ -125,7 +133,7 @@ public Request(StreamInput in) throws IOException {
@Override
public void writeTo(StreamOutput out) throws IOException {
super.writeTo(out);
out.writeStringCollection(indices);
out.writeStringArray(indices);
out.writeMap(fields, StreamOutput::writeFloat);
out.writeBoolean(resolveWildcards);
out.writeBoolean(useDefaultFields);
Expand Down Expand Up @@ -156,11 +164,18 @@ public ActionRequestValidationException validate() {
return validationException;
}

public Set<String> getIndices() {
return Collections.unmodifiableSet(indices);
@Override
public Request indices(String... indices) {
this.indices = indices;
return this;
}

@Override
public String[] indices() {
return indices;
}

public Map<String, Float> getFields() {
public Map<String, Float> fields() {
return Collections.unmodifiableMap(fields);
}

Expand All @@ -172,20 +187,26 @@ public boolean useDefaultFields() {
return useDefaultFields;
}

public String getQuery() {
public String query() {
return query;
}

public IndicesOptions getIndicesOptions() {
@Override
public IndicesOptions indicesOptions() {
return indicesOptions;
}

@Override
public boolean includeDataStreams() {
return true;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Request request = (Request) o;
return Objects.equals(indices, request.indices)
return Arrays.equals(indices, request.indices)
&& Objects.equals(fields, request.fields)
&& resolveWildcards == request.resolveWildcards
&& useDefaultFields == request.useDefaultFields
Expand All @@ -195,7 +216,7 @@ public boolean equals(Object o) {

@Override
public int hashCode() {
return Objects.hash(indices, fields, resolveWildcards, useDefaultFields, query, indicesOptions);
return Objects.hash(Arrays.hashCode(indices), fields, resolveWildcards, useDefaultFields, query, indicesOptions);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import org.elasticsearch.xpack.core.ccr.action.PutFollowAction;
import org.elasticsearch.xpack.core.ccr.action.UnfollowAction;
import org.elasticsearch.xpack.core.ilm.action.ExplainLifecycleAction;
import org.elasticsearch.xpack.core.inference.action.GetInferenceFieldsInternalAction;
import org.elasticsearch.xpack.core.rollup.action.GetRollupIndexCapsAction;
import org.elasticsearch.xpack.core.security.support.Automatons;
import org.elasticsearch.xpack.core.transform.action.GetCheckpointAction;
Expand Down Expand Up @@ -84,7 +85,8 @@ public final class IndexPrivilege extends Privilege {
private static final Automaton READ_AUTOMATON = patterns(
"indices:data/read/*",
ResolveIndexAction.NAME,
TransportResolveClusterAction.NAME
TransportResolveClusterAction.NAME,
GetInferenceFieldsInternalAction.NAME // cross-cluster inference for semantic search
);
private static final Automaton READ_FAILURE_STORE_AUTOMATON = patterns("indices:data/read/*", ResolveIndexAction.NAME);
private static final Automaton READ_CROSS_CLUSTER_AUTOMATON = patterns(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import org.elasticsearch.test.AbstractMultiClustersTestCase;
import org.elasticsearch.transport.RemoteClusterService;
import org.elasticsearch.xcontent.XContentBuilder;
import org.elasticsearch.xpack.core.inference.action.GetInferenceFieldsAction;
import org.elasticsearch.xpack.core.inference.action.GetInferenceFieldsInternalAction;
import org.elasticsearch.xpack.core.ml.inference.results.TextExpansionResults;
import org.elasticsearch.xpack.inference.FakeMlPlugin;
import org.elasticsearch.xpack.inference.LocalStateInferencePlugin;
Expand Down Expand Up @@ -47,8 +47,6 @@ public class GetInferenceFieldsCrossClusterIT extends AbstractMultiClustersTestC
private static final String INFERENCE_ID = "test-inference-id";
private static final Map<String, Object> INFERENCE_ENDPOINT_SERVICE_SETTINGS = Map.of("model", "my_model", "api_key", "my_api_key");

private boolean clustersConfigured = false;

@Override
protected List<String> remoteClusterAlias() {
return List.of(REMOTE_CLUSTER);
Expand All @@ -71,34 +69,43 @@ protected Collection<Class<? extends Plugin>> nodePlugins(String clusterAlias) {

@Before
public void configureClusters() throws Exception {
if (clustersConfigured == false) {
setupTwoClusters();
clustersConfigured = true;
}
setupTwoClusters();
}

public void testRemoteIndex() {
Consumer<GetInferenceFieldsAction.Request> assertFailedRequest = r -> {
Consumer<GetInferenceFieldsInternalAction.Request> assertFailedRequest = r -> {
IllegalArgumentException e = assertThrows(
IllegalArgumentException.class,
() -> client().execute(GetInferenceFieldsAction.INSTANCE, r).actionGet(TEST_REQUEST_TIMEOUT)
() -> client().execute(GetInferenceFieldsInternalAction.INSTANCE, r).actionGet(TEST_REQUEST_TIMEOUT)
);
assertThat(e.getMessage(), containsString("GetInferenceFieldsAction does not support remote indices"));
assertThat(e.getMessage(), containsString("GetInferenceFieldsInternalAction does not support remote indices"));
};

var concreteIndexRequest = new GetInferenceFieldsAction.Request(
Set.of(REMOTE_CLUSTER + ":test-index"),
var concreteIndexRequest = new GetInferenceFieldsInternalAction.Request(
new String[] { REMOTE_CLUSTER + ":test-index" },
Map.of(),
false,
false,
"foo"
);
assertFailedRequest.accept(concreteIndexRequest);

var wildcardIndexRequest = new GetInferenceFieldsAction.Request(Set.of(REMOTE_CLUSTER + ":*"), Map.of(), false, false, "foo");
var wildcardIndexRequest = new GetInferenceFieldsInternalAction.Request(
new String[] { REMOTE_CLUSTER + ":*" },
Map.of(),
false,
false,
"foo"
);
assertFailedRequest.accept(wildcardIndexRequest);

var wildcardClusterAndIndexRequest = new GetInferenceFieldsAction.Request(Set.of("*:*"), Map.of(), false, false, "foo");
var wildcardClusterAndIndexRequest = new GetInferenceFieldsInternalAction.Request(
new String[] { "*:*" },
Map.of(),
false,
false,
"foo"
);
assertFailedRequest.accept(wildcardClusterAndIndexRequest);
}

Expand All @@ -109,15 +116,15 @@ public void testRemoteClusterAction() {
RemoteClusterService.DisconnectedStrategy.RECONNECT_IF_DISCONNECTED
);

var request = new GetInferenceFieldsAction.Request(
Set.of(INDEX_NAME),
var request = new GetInferenceFieldsInternalAction.Request(
new String[] { INDEX_NAME },
generateDefaultWeightFieldMap(Set.of(INFERENCE_FIELD)),
false,
false,
"foo"
);
PlainActionFuture<GetInferenceFieldsAction.Response> future = new PlainActionFuture<>();
remoteClusterClient.execute(GetInferenceFieldsAction.REMOTE_TYPE, request, future);
PlainActionFuture<GetInferenceFieldsInternalAction.Response> future = new PlainActionFuture<>();
remoteClusterClient.execute(GetInferenceFieldsInternalAction.REMOTE_TYPE, request, future);

var response = future.actionGet(TEST_REQUEST_TIMEOUT);
assertInferenceFieldsMap(
Expand Down
Loading