|  | @@ -13,6 +13,7 @@ import org.elasticsearch.action.ActionRequest;
 | 
	
		
			
				|  |  |  import org.elasticsearch.action.ActionResponse;
 | 
	
		
			
				|  |  |  import org.elasticsearch.action.ActionType;
 | 
	
		
			
				|  |  |  import org.elasticsearch.client.internal.node.NodeClient;
 | 
	
		
			
				|  |  | +import org.elasticsearch.common.Strings;
 | 
	
		
			
				|  |  |  import org.elasticsearch.common.bytes.BytesArray;
 | 
	
		
			
				|  |  |  import org.elasticsearch.common.settings.Settings;
 | 
	
		
			
				|  |  |  import org.elasticsearch.env.Environment;
 | 
	
	
		
			
				|  | @@ -35,6 +36,7 @@ import org.elasticsearch.test.ESTestCase;
 | 
	
		
			
				|  |  |  import org.elasticsearch.test.rest.FakeRestRequest;
 | 
	
		
			
				|  |  |  import org.elasticsearch.threadpool.ThreadPool;
 | 
	
		
			
				|  |  |  import org.elasticsearch.xcontent.NamedXContentRegistry;
 | 
	
		
			
				|  |  | +import org.elasticsearch.xcontent.XContentParseException;
 | 
	
		
			
				|  |  |  import org.elasticsearch.xcontent.XContentParser;
 | 
	
		
			
				|  |  |  import org.elasticsearch.xcontent.XContentType;
 | 
	
		
			
				|  |  |  import org.elasticsearch.xpack.core.security.action.apikey.ApiKey;
 | 
	
	
		
			
				|  | @@ -48,6 +50,7 @@ import java.util.List;
 | 
	
		
			
				|  |  |  import java.util.Map;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import static org.hamcrest.Matchers.contains;
 | 
	
		
			
				|  |  | +import static org.hamcrest.Matchers.containsString;
 | 
	
		
			
				|  |  |  import static org.hamcrest.Matchers.equalTo;
 | 
	
		
			
				|  |  |  import static org.hamcrest.Matchers.hasSize;
 | 
	
		
			
				|  |  |  import static org.hamcrest.Matchers.is;
 | 
	
	
		
			
				|  | @@ -145,6 +148,69 @@ public class RestQueryApiKeyActionTests extends ESTestCase {
 | 
	
		
			
				|  |  |          assertNotNull(responseSetOnce.get());
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    public void testAggsAndAggregationsTogether() {
 | 
	
		
			
				|  |  | +        String agg1;
 | 
	
		
			
				|  |  | +        String agg2;
 | 
	
		
			
				|  |  | +        if (randomBoolean()) {
 | 
	
		
			
				|  |  | +            agg1 = "aggs";
 | 
	
		
			
				|  |  | +            agg2 = "aggregations";
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +            agg1 = "aggregations";
 | 
	
		
			
				|  |  | +            agg2 = "aggs";
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        final String requestBody = Strings.format("""
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +              "%s": {
 | 
	
		
			
				|  |  | +                "all_keys_by_type": {
 | 
	
		
			
				|  |  | +                  "composite": {
 | 
	
		
			
				|  |  | +                    "sources": [
 | 
	
		
			
				|  |  | +                      { "type": { "terms": { "field": "type" } } }
 | 
	
		
			
				|  |  | +                    ]
 | 
	
		
			
				|  |  | +                  }
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +              },
 | 
	
		
			
				|  |  | +              "%s": {
 | 
	
		
			
				|  |  | +                "type_cardinality": {
 | 
	
		
			
				|  |  | +                  "cardinality": {
 | 
	
		
			
				|  |  | +                    "field": "type"
 | 
	
		
			
				|  |  | +                  }
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +              }
 | 
	
		
			
				|  |  | +            }""", agg1, agg2);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        final FakeRestRequest restRequest = new FakeRestRequest.Builder(xContentRegistry()).withContent(
 | 
	
		
			
				|  |  | +            new BytesArray(requestBody),
 | 
	
		
			
				|  |  | +            XContentType.JSON
 | 
	
		
			
				|  |  | +        ).build();
 | 
	
		
			
				|  |  | +        final SetOnce<RestResponse> responseSetOnce = new SetOnce<>();
 | 
	
		
			
				|  |  | +        final RestChannel restChannel = new AbstractRestChannel(restRequest, randomBoolean()) {
 | 
	
		
			
				|  |  | +            @Override
 | 
	
		
			
				|  |  | +            public void sendResponse(RestResponse restResponse) {
 | 
	
		
			
				|  |  | +                responseSetOnce.set(restResponse);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        };
 | 
	
		
			
				|  |  | +        final var client = new NodeClient(Settings.EMPTY, threadPool) {
 | 
	
		
			
				|  |  | +            @SuppressWarnings("unchecked")
 | 
	
		
			
				|  |  | +            @Override
 | 
	
		
			
				|  |  | +            public <Request extends ActionRequest, Response extends ActionResponse> void doExecute(
 | 
	
		
			
				|  |  | +                ActionType<Response> action,
 | 
	
		
			
				|  |  | +                Request request,
 | 
	
		
			
				|  |  | +                ActionListener<Response> listener
 | 
	
		
			
				|  |  | +            ) {
 | 
	
		
			
				|  |  | +                fail("TEST failed, request parsing should've failed");
 | 
	
		
			
				|  |  | +                listener.onResponse((Response) QueryApiKeyResponse.EMPTY);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        };
 | 
	
		
			
				|  |  | +        RestQueryApiKeyAction restQueryApiKeyAction = new RestQueryApiKeyAction(Settings.EMPTY, mockLicenseState);
 | 
	
		
			
				|  |  | +        XContentParseException ex = expectThrows(
 | 
	
		
			
				|  |  | +            XContentParseException.class,
 | 
	
		
			
				|  |  | +            () -> restQueryApiKeyAction.handleRequest(restRequest, restChannel, client)
 | 
	
		
			
				|  |  | +        );
 | 
	
		
			
				|  |  | +        assertThat(ex.getCause().getMessage(), containsString("Duplicate 'aggs' or 'aggregations' field"));
 | 
	
		
			
				|  |  | +        assertThat(ex.getMessage(), containsString("Failed to build [query_api_key_request_payload]"));
 | 
	
		
			
				|  |  | +        assertNull(responseSetOnce.get());
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      public void testParsingSearchParameters() throws Exception {
 | 
	
		
			
				|  |  |          final String requestBody = """
 | 
	
		
			
				|  |  |              {
 |