From 1004ef7422c808b027f164ec733033b732b66609 Mon Sep 17 00:00:00 2001 From: Craig Perkins Date: Wed, 1 Nov 2023 17:11:23 -0400 Subject: [PATCH 1/9] Add async test to ensure bulk requests succeed while cache is invalidated Signed-off-by: Craig Perkins --- .../opensearch/security/http/AsyncTests.java | 115 ++++++++++++++++++ .../security/http/BasicAuthTests.java | 2 +- .../test/framework/AsyncActions.java | 2 + .../test/framework/TestSecurityConfig.java | 42 ++++++- 4 files changed, 157 insertions(+), 4 deletions(-) create mode 100644 src/integrationTest/java/org/opensearch/security/http/AsyncTests.java diff --git a/src/integrationTest/java/org/opensearch/security/http/AsyncTests.java b/src/integrationTest/java/org/opensearch/security/http/AsyncTests.java new file mode 100644 index 0000000000..81759b5291 --- /dev/null +++ b/src/integrationTest/java/org/opensearch/security/http/AsyncTests.java @@ -0,0 +1,115 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + * + */ + +package org.opensearch.security.http; + +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope; +import com.nimbusds.jose.util.StandardCharset; + +import org.apache.hc.client5.http.classic.methods.HttpDelete; +import org.apache.hc.client5.http.classic.methods.HttpGet; +import org.apache.hc.client5.http.classic.methods.HttpPost; +import org.apache.hc.core5.http.ContentType; +import org.apache.hc.core5.http.HttpStatus; +import org.apache.hc.core5.http.io.entity.ByteArrayEntity; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.opensearch.security.IndexOperationsHelper; +import org.opensearch.security.support.ConfigConstants; +import org.opensearch.test.framework.AsyncActions; +import org.opensearch.test.framework.RolesMapping; +import org.opensearch.test.framework.TestSecurityConfig; +import org.opensearch.test.framework.cluster.LocalCluster; +import org.opensearch.test.framework.cluster.TestRestClient; +import org.opensearch.test.framework.cluster.TestRestClient.HttpResponse; + +import java.util.Collections; +import java.util.Map; +import java.util.List; +import java.util.ArrayList; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.CompletableFuture; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.opensearch.test.framework.TestSecurityConfig.AuthcDomain.AUTHC_HTTPBASIC_INTERNAL; +import static org.opensearch.test.framework.TestSecurityConfig.Role.ALL_ACCESS; +import static org.opensearch.test.framework.cluster.TestRestClientConfiguration.getBasicAuthHeader; + +@RunWith(com.carrotsearch.randomizedtesting.RandomizedRunner.class) +@ThreadLeakScope(ThreadLeakScope.Scope.NONE) +public class AsyncTests { + private static final TestSecurityConfig.User ADMIN_USER = new TestSecurityConfig.User("admin").backendRoles("admin"); + + @ClassRule + public static LocalCluster cluster = new LocalCluster.Builder().singleNode() + .authc(AUTHC_HTTPBASIC_INTERNAL) + .users(ADMIN_USER) + .rolesMapping(new RolesMapping(ALL_ACCESS).backendRoles("admin")) + .anonymousAuth(false) + .nodeSettings(Map.of(ConfigConstants.SECURITY_RESTAPI_ROLES_ENABLED, List.of(ALL_ACCESS.getName()))) + .build(); + + @Test + public void testIndexAndCacheInvalidationMixed() throws Exception { + String indexName = "test-index"; + final String invalidateCachePath = "/_plugins/_security/api/cache"; + final String nodesPath = "/_nodes"; + final String bulkPath = "/_bulk"; + final String document = ("{ \"index\": { \"_index\": \"" + indexName + "\" }}\n{ \"foo\": \"bar\" }\n").repeat(5); + final int parallelism = 5; + final int totalNumberOfRequests = 30; + + try (final TestRestClient client = cluster.getRestClient()) { + IndexOperationsHelper.createIndex(cluster, indexName); + + final CountDownLatch countDownLatch = new CountDownLatch(1); + + final var cacheInvalidationRequests = AsyncActions.generate(() -> { + countDownLatch.await(); + System.err.println("Generation triggered invalidate cache requests"); + final HttpDelete delete = new HttpDelete(client.getHttpServerUri() + invalidateCachePath); + return client.executeRequest(delete, getBasicAuthHeader(ADMIN_USER.getName(), ADMIN_USER.getPassword())); + }, parallelism, totalNumberOfRequests); + + final var bulkRequests = AsyncActions.generate(() -> { + countDownLatch.await(); + System.err.println("Generation triggered bulk requests"); + final HttpPost post = new HttpPost(client.getHttpServerUri() + bulkPath); + post.setEntity(new ByteArrayEntity(document.getBytes(StandardCharset.UTF_8), ContentType.APPLICATION_JSON)); + return client.executeRequest(post, getBasicAuthHeader(ADMIN_USER.getName(), ADMIN_USER.getPassword())); + }, parallelism, totalNumberOfRequests); + + final var nodesRequests = AsyncActions.generate(() -> { + countDownLatch.await(); + System.err.println("Generation triggered node requests"); + final HttpGet get = new HttpGet(client.getHttpServerUri() + nodesPath); + return client.executeRequest(get, getBasicAuthHeader(ADMIN_USER.getName(), ADMIN_USER.getPassword())); + }, parallelism, totalNumberOfRequests); + + // Make sure all requests start at the same time + countDownLatch.countDown(); + + List> allRequests = new ArrayList>(); + allRequests.addAll(cacheInvalidationRequests); + allRequests.addAll(bulkRequests); + allRequests.addAll(nodesRequests); + Collections.shuffle(allRequests); + AsyncActions.getAll(allRequests, 150, TimeUnit.SECONDS).forEach((response) -> { + if (response.getStatusCode() == HttpStatus.SC_INTERNAL_SERVER_ERROR) { + System.out.println("Response body: " + response.getBody()); + } + assertThat(response.getStatusCode(), equalTo(HttpStatus.SC_OK)); + }); + } + } +} diff --git a/src/integrationTest/java/org/opensearch/security/http/BasicAuthTests.java b/src/integrationTest/java/org/opensearch/security/http/BasicAuthTests.java index f6b1672bbe..1e424ab115 100644 --- a/src/integrationTest/java/org/opensearch/security/http/BasicAuthTests.java +++ b/src/integrationTest/java/org/opensearch/security/http/BasicAuthTests.java @@ -40,7 +40,7 @@ public class BasicAuthTests { static final User TEST_USER = new User("test_user").password("s3cret"); public static final String CUSTOM_ATTRIBUTE_NAME = "superhero"; - static final User SUPER_USER = new User("super-user").password("super-password").attr(CUSTOM_ATTRIBUTE_NAME, true); + static final User SUPER_USER = new User("super-user").password("super-password").attr(CUSTOM_ATTRIBUTE_NAME, "true"); public static final String NOT_EXISTING_USER = "not-existing-user"; public static final String INVALID_PASSWORD = "secret-password"; diff --git a/src/integrationTest/java/org/opensearch/test/framework/AsyncActions.java b/src/integrationTest/java/org/opensearch/test/framework/AsyncActions.java index 409aa5a416..3a58b1d093 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/AsyncActions.java +++ b/src/integrationTest/java/org/opensearch/test/framework/AsyncActions.java @@ -55,6 +55,8 @@ public static List getAll(final List> futures, final try { futuresCompleted.get(n, unit); } catch (final Exception ex) { + System.out.println("Got exception: " + ex.getMessage()); + ex.printStackTrace(); final long completedFuturesCount = futures.stream().filter(CompletableFuture::isDone).count(); final String perfReport = calculatePerfReport(startTimeMs, completedFuturesCount); throw new RuntimeException( diff --git a/src/integrationTest/java/org/opensearch/test/framework/TestSecurityConfig.java b/src/integrationTest/java/org/opensearch/test/framework/TestSecurityConfig.java index 2fd3fc474d..6b94fa7750 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/TestSecurityConfig.java +++ b/src/integrationTest/java/org/opensearch/test/framework/TestSecurityConfig.java @@ -29,6 +29,7 @@ package org.opensearch.test.framework; import java.io.IOException; +import java.io.Serializable; import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; import java.security.SecureRandom; @@ -58,6 +59,9 @@ import org.opensearch.core.xcontent.XContentBuilder; import org.opensearch.security.securityconf.impl.CType; import org.opensearch.test.framework.cluster.OpenSearchClientProvider.UserCredentialsHolder; +import org.opensearch.core.common.io.stream.StreamInput; +import org.opensearch.core.common.io.stream.StreamOutput; +import org.opensearch.core.common.io.stream.Writeable; import static org.apache.http.HttpHeaders.AUTHORIZATION; import static org.opensearch.action.support.WriteRequest.RefreshPolicy.IMMEDIATE; @@ -252,7 +256,7 @@ public XContentBuilder toXContent(XContentBuilder xContentBuilder, Params params } } - public static class User implements UserCredentialsHolder, ToXContentObject { + public static class User implements UserCredentialsHolder, ToXContentObject, Serializable, Writeable { public final static TestSecurityConfig.User USER_ADMIN = new TestSecurityConfig.User("admin").roles( new Role("allaccess").indexPermissions("*").on("*").clusterPermissions("*") @@ -261,13 +265,27 @@ public static class User implements UserCredentialsHolder, ToXContentObject { String name; private String password; List roles = new ArrayList<>(); - private Map attributes = new HashMap<>(); + List backendRoles = new ArrayList<>(); + String requestedTenant; + private Map attributes = new HashMap<>(); public User(String name) { this.name = name; this.password = "secret"; } + public User(final StreamInput in) throws IOException { + super(); + name = in.readString(); + roles.addAll(in.readList(StreamInput::readString).stream().map(r -> new Role(r)).collect(Collectors.toList())); + requestedTenant = in.readString(); + if (requestedTenant.isEmpty()) { + requestedTenant = null; + } + attributes = in.readMap(StreamInput::readString, StreamInput::readString); + backendRoles.addAll(in.readList(StreamInput::readString)); + } + public User password(String password) { this.password = password; return this; @@ -282,7 +300,12 @@ public User roles(Role... roles) { return this; } - public User attr(String key, Object value) { + public User backendRoles(String... backendRoles) { + this.backendRoles.addAll(Arrays.asList(backendRoles)); + return this; + } + + public User attr(String key, String value) { this.attributes.put(key, value); return this; } @@ -315,6 +338,10 @@ public XContentBuilder toXContent(XContentBuilder xContentBuilder, Params params xContentBuilder.field("opendistro_security_roles", roleNames); } + if (!backendRoles.isEmpty()) { + xContentBuilder.field("backend_roles", backendRoles); + } + if (attributes != null && attributes.size() != 0) { xContentBuilder.field("attributes", attributes); } @@ -322,6 +349,15 @@ public XContentBuilder toXContent(XContentBuilder xContentBuilder, Params params xContentBuilder.endObject(); return xContentBuilder; } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeString(name); + out.writeStringCollection(roles.stream().map(r -> r.getName()).collect(Collectors.toList())); + out.writeString(requestedTenant == null ? "" : requestedTenant); + out.writeMap(attributes, StreamOutput::writeString, StreamOutput::writeString); + out.writeStringCollection(backendRoles == null ? Collections.emptyList() : new ArrayList(backendRoles)); + } } public static class Role implements ToXContentObject { From 7ebe917f6a1457190ae2cad3feaee2907b443329 Mon Sep 17 00:00:00 2001 From: Craig Perkins Date: Wed, 1 Nov 2023 17:19:43 -0400 Subject: [PATCH 2/9] Change test name Signed-off-by: Craig Perkins --- .../java/org/opensearch/security/http/AsyncTests.java | 2 +- .../java/org/opensearch/test/framework/AsyncActions.java | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/integrationTest/java/org/opensearch/security/http/AsyncTests.java b/src/integrationTest/java/org/opensearch/security/http/AsyncTests.java index 81759b5291..fe878411af 100644 --- a/src/integrationTest/java/org/opensearch/security/http/AsyncTests.java +++ b/src/integrationTest/java/org/opensearch/security/http/AsyncTests.java @@ -60,7 +60,7 @@ public class AsyncTests { .build(); @Test - public void testIndexAndCacheInvalidationMixed() throws Exception { + public void testBulkAndCacheInvalidationMixed() throws Exception { String indexName = "test-index"; final String invalidateCachePath = "/_plugins/_security/api/cache"; final String nodesPath = "/_nodes"; diff --git a/src/integrationTest/java/org/opensearch/test/framework/AsyncActions.java b/src/integrationTest/java/org/opensearch/test/framework/AsyncActions.java index 3a58b1d093..409aa5a416 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/AsyncActions.java +++ b/src/integrationTest/java/org/opensearch/test/framework/AsyncActions.java @@ -55,8 +55,6 @@ public static List getAll(final List> futures, final try { futuresCompleted.get(n, unit); } catch (final Exception ex) { - System.out.println("Got exception: " + ex.getMessage()); - ex.printStackTrace(); final long completedFuturesCount = futures.stream().filter(CompletableFuture::isDone).count(); final String perfReport = calculatePerfReport(startTimeMs, completedFuturesCount); throw new RuntimeException( From 9e1bfad228997e7c196b5ac8a559a95144271f67 Mon Sep 17 00:00:00 2001 From: Craig Perkins Date: Thu, 2 Nov 2023 15:41:37 -0400 Subject: [PATCH 3/9] Remove Serializable from implementation list Signed-off-by: Craig Perkins --- .../java/org/opensearch/test/framework/TestSecurityConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/integrationTest/java/org/opensearch/test/framework/TestSecurityConfig.java b/src/integrationTest/java/org/opensearch/test/framework/TestSecurityConfig.java index 6b94fa7750..0f2c83af13 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/TestSecurityConfig.java +++ b/src/integrationTest/java/org/opensearch/test/framework/TestSecurityConfig.java @@ -256,7 +256,7 @@ public XContentBuilder toXContent(XContentBuilder xContentBuilder, Params params } } - public static class User implements UserCredentialsHolder, ToXContentObject, Serializable, Writeable { + public static class User implements UserCredentialsHolder, ToXContentObject, Writeable { public final static TestSecurityConfig.User USER_ADMIN = new TestSecurityConfig.User("admin").roles( new Role("allaccess").indexPermissions("*").on("*").clusterPermissions("*") From 87a767f16a50e96033453ba4158a274db4bdb91d Mon Sep 17 00:00:00 2001 From: Craig Perkins Date: Thu, 2 Nov 2023 16:07:03 -0400 Subject: [PATCH 4/9] Fix checkstyle Signed-off-by: Craig Perkins --- .../java/org/opensearch/security/http/AsyncTests.java | 3 --- .../java/org/opensearch/test/framework/TestSecurityConfig.java | 1 - 2 files changed, 4 deletions(-) diff --git a/src/integrationTest/java/org/opensearch/security/http/AsyncTests.java b/src/integrationTest/java/org/opensearch/security/http/AsyncTests.java index fe878411af..3cf53500cf 100644 --- a/src/integrationTest/java/org/opensearch/security/http/AsyncTests.java +++ b/src/integrationTest/java/org/opensearch/security/http/AsyncTests.java @@ -105,9 +105,6 @@ public void testBulkAndCacheInvalidationMixed() throws Exception { allRequests.addAll(nodesRequests); Collections.shuffle(allRequests); AsyncActions.getAll(allRequests, 150, TimeUnit.SECONDS).forEach((response) -> { - if (response.getStatusCode() == HttpStatus.SC_INTERNAL_SERVER_ERROR) { - System.out.println("Response body: " + response.getBody()); - } assertThat(response.getStatusCode(), equalTo(HttpStatus.SC_OK)); }); } diff --git a/src/integrationTest/java/org/opensearch/test/framework/TestSecurityConfig.java b/src/integrationTest/java/org/opensearch/test/framework/TestSecurityConfig.java index 0f2c83af13..f9dca443db 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/TestSecurityConfig.java +++ b/src/integrationTest/java/org/opensearch/test/framework/TestSecurityConfig.java @@ -29,7 +29,6 @@ package org.opensearch.test.framework; import java.io.IOException; -import java.io.Serializable; import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; import java.security.SecureRandom; From a65c4ff99d087dca795071d7d2ebb7436cb05db1 Mon Sep 17 00:00:00 2001 From: Craig Perkins Date: Thu, 2 Nov 2023 16:24:11 -0400 Subject: [PATCH 5/9] Address some code review comments Signed-off-by: Craig Perkins --- .../opensearch/security/http/AsyncTests.java | 9 +------ .../test/framework/TestSecurityConfig.java | 26 +------------------ 2 files changed, 2 insertions(+), 33 deletions(-) diff --git a/src/integrationTest/java/org/opensearch/security/http/AsyncTests.java b/src/integrationTest/java/org/opensearch/security/http/AsyncTests.java index 3cf53500cf..170d358117 100644 --- a/src/integrationTest/java/org/opensearch/security/http/AsyncTests.java +++ b/src/integrationTest/java/org/opensearch/security/http/AsyncTests.java @@ -39,8 +39,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.CompletableFuture; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.MatcherAssert.assertThat; import static org.opensearch.test.framework.TestSecurityConfig.AuthcDomain.AUTHC_HTTPBASIC_INTERNAL; import static org.opensearch.test.framework.TestSecurityConfig.Role.ALL_ACCESS; import static org.opensearch.test.framework.cluster.TestRestClientConfiguration.getBasicAuthHeader; @@ -76,14 +74,12 @@ public void testBulkAndCacheInvalidationMixed() throws Exception { final var cacheInvalidationRequests = AsyncActions.generate(() -> { countDownLatch.await(); - System.err.println("Generation triggered invalidate cache requests"); final HttpDelete delete = new HttpDelete(client.getHttpServerUri() + invalidateCachePath); return client.executeRequest(delete, getBasicAuthHeader(ADMIN_USER.getName(), ADMIN_USER.getPassword())); }, parallelism, totalNumberOfRequests); final var bulkRequests = AsyncActions.generate(() -> { countDownLatch.await(); - System.err.println("Generation triggered bulk requests"); final HttpPost post = new HttpPost(client.getHttpServerUri() + bulkPath); post.setEntity(new ByteArrayEntity(document.getBytes(StandardCharset.UTF_8), ContentType.APPLICATION_JSON)); return client.executeRequest(post, getBasicAuthHeader(ADMIN_USER.getName(), ADMIN_USER.getPassword())); @@ -91,7 +87,6 @@ public void testBulkAndCacheInvalidationMixed() throws Exception { final var nodesRequests = AsyncActions.generate(() -> { countDownLatch.await(); - System.err.println("Generation triggered node requests"); final HttpGet get = new HttpGet(client.getHttpServerUri() + nodesPath); return client.executeRequest(get, getBasicAuthHeader(ADMIN_USER.getName(), ADMIN_USER.getPassword())); }, parallelism, totalNumberOfRequests); @@ -104,9 +99,7 @@ public void testBulkAndCacheInvalidationMixed() throws Exception { allRequests.addAll(bulkRequests); allRequests.addAll(nodesRequests); Collections.shuffle(allRequests); - AsyncActions.getAll(allRequests, 150, TimeUnit.SECONDS).forEach((response) -> { - assertThat(response.getStatusCode(), equalTo(HttpStatus.SC_OK)); - }); + AsyncActions.getAll(allRequests, 30, TimeUnit.SECONDS).forEach((response) -> { response.assertStatusCode(HttpStatus.SC_OK); }); } } } diff --git a/src/integrationTest/java/org/opensearch/test/framework/TestSecurityConfig.java b/src/integrationTest/java/org/opensearch/test/framework/TestSecurityConfig.java index f9dca443db..71a8aad545 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/TestSecurityConfig.java +++ b/src/integrationTest/java/org/opensearch/test/framework/TestSecurityConfig.java @@ -58,9 +58,6 @@ import org.opensearch.core.xcontent.XContentBuilder; import org.opensearch.security.securityconf.impl.CType; import org.opensearch.test.framework.cluster.OpenSearchClientProvider.UserCredentialsHolder; -import org.opensearch.core.common.io.stream.StreamInput; -import org.opensearch.core.common.io.stream.StreamOutput; -import org.opensearch.core.common.io.stream.Writeable; import static org.apache.http.HttpHeaders.AUTHORIZATION; import static org.opensearch.action.support.WriteRequest.RefreshPolicy.IMMEDIATE; @@ -255,7 +252,7 @@ public XContentBuilder toXContent(XContentBuilder xContentBuilder, Params params } } - public static class User implements UserCredentialsHolder, ToXContentObject, Writeable { + public static class User implements UserCredentialsHolder, ToXContentObject { public final static TestSecurityConfig.User USER_ADMIN = new TestSecurityConfig.User("admin").roles( new Role("allaccess").indexPermissions("*").on("*").clusterPermissions("*") @@ -273,18 +270,6 @@ public User(String name) { this.password = "secret"; } - public User(final StreamInput in) throws IOException { - super(); - name = in.readString(); - roles.addAll(in.readList(StreamInput::readString).stream().map(r -> new Role(r)).collect(Collectors.toList())); - requestedTenant = in.readString(); - if (requestedTenant.isEmpty()) { - requestedTenant = null; - } - attributes = in.readMap(StreamInput::readString, StreamInput::readString); - backendRoles.addAll(in.readList(StreamInput::readString)); - } - public User password(String password) { this.password = password; return this; @@ -348,15 +333,6 @@ public XContentBuilder toXContent(XContentBuilder xContentBuilder, Params params xContentBuilder.endObject(); return xContentBuilder; } - - @Override - public void writeTo(StreamOutput out) throws IOException { - out.writeString(name); - out.writeStringCollection(roles.stream().map(r -> r.getName()).collect(Collectors.toList())); - out.writeString(requestedTenant == null ? "" : requestedTenant); - out.writeMap(attributes, StreamOutput::writeString, StreamOutput::writeString); - out.writeStringCollection(backendRoles == null ? Collections.emptyList() : new ArrayList(backendRoles)); - } } public static class Role implements ToXContentObject { From 8b0683214602387c3b99542ed2701e5d0e8dc59b Mon Sep 17 00:00:00 2001 From: Craig Perkins Date: Thu, 2 Nov 2023 16:31:49 -0400 Subject: [PATCH 6/9] Reduce number of variables Signed-off-by: Craig Perkins --- .../opensearch/security/http/AsyncTests.java | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/integrationTest/java/org/opensearch/security/http/AsyncTests.java b/src/integrationTest/java/org/opensearch/security/http/AsyncTests.java index 170d358117..b1400b7898 100644 --- a/src/integrationTest/java/org/opensearch/security/http/AsyncTests.java +++ b/src/integrationTest/java/org/opensearch/security/http/AsyncTests.java @@ -72,33 +72,31 @@ public void testBulkAndCacheInvalidationMixed() throws Exception { final CountDownLatch countDownLatch = new CountDownLatch(1); - final var cacheInvalidationRequests = AsyncActions.generate(() -> { + List> allRequests = new ArrayList>(); + + allRequests.addAll(AsyncActions.generate(() -> { countDownLatch.await(); final HttpDelete delete = new HttpDelete(client.getHttpServerUri() + invalidateCachePath); return client.executeRequest(delete, getBasicAuthHeader(ADMIN_USER.getName(), ADMIN_USER.getPassword())); - }, parallelism, totalNumberOfRequests); + }, parallelism, totalNumberOfRequests)); - final var bulkRequests = AsyncActions.generate(() -> { + allRequests.addAll(AsyncActions.generate(() -> { countDownLatch.await(); final HttpPost post = new HttpPost(client.getHttpServerUri() + bulkPath); post.setEntity(new ByteArrayEntity(document.getBytes(StandardCharset.UTF_8), ContentType.APPLICATION_JSON)); return client.executeRequest(post, getBasicAuthHeader(ADMIN_USER.getName(), ADMIN_USER.getPassword())); - }, parallelism, totalNumberOfRequests); + }, parallelism, totalNumberOfRequests)); - final var nodesRequests = AsyncActions.generate(() -> { + allRequests.addAll(AsyncActions.generate(() -> { countDownLatch.await(); final HttpGet get = new HttpGet(client.getHttpServerUri() + nodesPath); return client.executeRequest(get, getBasicAuthHeader(ADMIN_USER.getName(), ADMIN_USER.getPassword())); - }, parallelism, totalNumberOfRequests); + }, parallelism, totalNumberOfRequests)); // Make sure all requests start at the same time countDownLatch.countDown(); - - List> allRequests = new ArrayList>(); - allRequests.addAll(cacheInvalidationRequests); - allRequests.addAll(bulkRequests); - allRequests.addAll(nodesRequests); Collections.shuffle(allRequests); + AsyncActions.getAll(allRequests, 30, TimeUnit.SECONDS).forEach((response) -> { response.assertStatusCode(HttpStatus.SC_OK); }); } } From 0ed37277ed12899b5634d9863e41e73da41c0a91 Mon Sep 17 00:00:00 2001 From: Craig Perkins Date: Thu, 2 Nov 2023 16:37:01 -0400 Subject: [PATCH 7/9] Instantiate restclient with AdminUser Signed-off-by: Craig Perkins --- .../java/org/opensearch/security/http/AsyncTests.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/integrationTest/java/org/opensearch/security/http/AsyncTests.java b/src/integrationTest/java/org/opensearch/security/http/AsyncTests.java index b1400b7898..efd21d5e2e 100644 --- a/src/integrationTest/java/org/opensearch/security/http/AsyncTests.java +++ b/src/integrationTest/java/org/opensearch/security/http/AsyncTests.java @@ -41,7 +41,6 @@ import static org.opensearch.test.framework.TestSecurityConfig.AuthcDomain.AUTHC_HTTPBASIC_INTERNAL; import static org.opensearch.test.framework.TestSecurityConfig.Role.ALL_ACCESS; -import static org.opensearch.test.framework.cluster.TestRestClientConfiguration.getBasicAuthHeader; @RunWith(com.carrotsearch.randomizedtesting.RandomizedRunner.class) @ThreadLeakScope(ThreadLeakScope.Scope.NONE) @@ -67,7 +66,7 @@ public void testBulkAndCacheInvalidationMixed() throws Exception { final int parallelism = 5; final int totalNumberOfRequests = 30; - try (final TestRestClient client = cluster.getRestClient()) { + try (final TestRestClient client = cluster.getRestClient(ADMIN_USER)) { IndexOperationsHelper.createIndex(cluster, indexName); final CountDownLatch countDownLatch = new CountDownLatch(1); @@ -77,20 +76,20 @@ public void testBulkAndCacheInvalidationMixed() throws Exception { allRequests.addAll(AsyncActions.generate(() -> { countDownLatch.await(); final HttpDelete delete = new HttpDelete(client.getHttpServerUri() + invalidateCachePath); - return client.executeRequest(delete, getBasicAuthHeader(ADMIN_USER.getName(), ADMIN_USER.getPassword())); + return client.executeRequest(delete); }, parallelism, totalNumberOfRequests)); allRequests.addAll(AsyncActions.generate(() -> { countDownLatch.await(); final HttpPost post = new HttpPost(client.getHttpServerUri() + bulkPath); post.setEntity(new ByteArrayEntity(document.getBytes(StandardCharset.UTF_8), ContentType.APPLICATION_JSON)); - return client.executeRequest(post, getBasicAuthHeader(ADMIN_USER.getName(), ADMIN_USER.getPassword())); + return client.executeRequest(post); }, parallelism, totalNumberOfRequests)); allRequests.addAll(AsyncActions.generate(() -> { countDownLatch.await(); final HttpGet get = new HttpGet(client.getHttpServerUri() + nodesPath); - return client.executeRequest(get, getBasicAuthHeader(ADMIN_USER.getName(), ADMIN_USER.getPassword())); + return client.executeRequest(get); }, parallelism, totalNumberOfRequests)); // Make sure all requests start at the same time From 6a785c753669f957e899c717d62103f88ad4e30b Mon Sep 17 00:00:00 2001 From: Craig Perkins Date: Thu, 2 Nov 2023 16:44:40 -0400 Subject: [PATCH 8/9] Use client.delete and client.get Signed-off-by: Craig Perkins --- .../org/opensearch/security/http/AsyncTests.java | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/integrationTest/java/org/opensearch/security/http/AsyncTests.java b/src/integrationTest/java/org/opensearch/security/http/AsyncTests.java index efd21d5e2e..db6c940b1f 100644 --- a/src/integrationTest/java/org/opensearch/security/http/AsyncTests.java +++ b/src/integrationTest/java/org/opensearch/security/http/AsyncTests.java @@ -13,8 +13,6 @@ import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope; import com.nimbusds.jose.util.StandardCharset; -import org.apache.hc.client5.http.classic.methods.HttpDelete; -import org.apache.hc.client5.http.classic.methods.HttpGet; import org.apache.hc.client5.http.classic.methods.HttpPost; import org.apache.hc.core5.http.ContentType; import org.apache.hc.core5.http.HttpStatus; @@ -59,8 +57,8 @@ public class AsyncTests { @Test public void testBulkAndCacheInvalidationMixed() throws Exception { String indexName = "test-index"; - final String invalidateCachePath = "/_plugins/_security/api/cache"; - final String nodesPath = "/_nodes"; + final String invalidateCachePath = "_plugins/_security/api/cache"; + final String nodesPath = "_nodes"; final String bulkPath = "/_bulk"; final String document = ("{ \"index\": { \"_index\": \"" + indexName + "\" }}\n{ \"foo\": \"bar\" }\n").repeat(5); final int parallelism = 5; @@ -75,8 +73,7 @@ public void testBulkAndCacheInvalidationMixed() throws Exception { allRequests.addAll(AsyncActions.generate(() -> { countDownLatch.await(); - final HttpDelete delete = new HttpDelete(client.getHttpServerUri() + invalidateCachePath); - return client.executeRequest(delete); + return client.delete(invalidateCachePath); }, parallelism, totalNumberOfRequests)); allRequests.addAll(AsyncActions.generate(() -> { @@ -88,8 +85,7 @@ public void testBulkAndCacheInvalidationMixed() throws Exception { allRequests.addAll(AsyncActions.generate(() -> { countDownLatch.await(); - final HttpGet get = new HttpGet(client.getHttpServerUri() + nodesPath); - return client.executeRequest(get); + return client.get(nodesPath); }, parallelism, totalNumberOfRequests)); // Make sure all requests start at the same time From 0ce56e7d94e5a1bd31640996074acbb1250e8f77 Mon Sep 17 00:00:00 2001 From: Craig Perkins Date: Thu, 2 Nov 2023 20:06:29 -0400 Subject: [PATCH 9/9] Switch to postJson and remove shuffle Signed-off-by: Craig Perkins --- .../org/opensearch/security/http/AsyncTests.java | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/integrationTest/java/org/opensearch/security/http/AsyncTests.java b/src/integrationTest/java/org/opensearch/security/http/AsyncTests.java index db6c940b1f..ee46fb3905 100644 --- a/src/integrationTest/java/org/opensearch/security/http/AsyncTests.java +++ b/src/integrationTest/java/org/opensearch/security/http/AsyncTests.java @@ -11,12 +11,8 @@ package org.opensearch.security.http; import com.carrotsearch.randomizedtesting.annotations.ThreadLeakScope; -import com.nimbusds.jose.util.StandardCharset; -import org.apache.hc.client5.http.classic.methods.HttpPost; -import org.apache.hc.core5.http.ContentType; import org.apache.hc.core5.http.HttpStatus; -import org.apache.hc.core5.http.io.entity.ByteArrayEntity; import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; @@ -29,7 +25,6 @@ import org.opensearch.test.framework.cluster.TestRestClient; import org.opensearch.test.framework.cluster.TestRestClient.HttpResponse; -import java.util.Collections; import java.util.Map; import java.util.List; import java.util.ArrayList; @@ -59,7 +54,7 @@ public void testBulkAndCacheInvalidationMixed() throws Exception { String indexName = "test-index"; final String invalidateCachePath = "_plugins/_security/api/cache"; final String nodesPath = "_nodes"; - final String bulkPath = "/_bulk"; + final String bulkPath = "_bulk"; final String document = ("{ \"index\": { \"_index\": \"" + indexName + "\" }}\n{ \"foo\": \"bar\" }\n").repeat(5); final int parallelism = 5; final int totalNumberOfRequests = 30; @@ -78,9 +73,7 @@ public void testBulkAndCacheInvalidationMixed() throws Exception { allRequests.addAll(AsyncActions.generate(() -> { countDownLatch.await(); - final HttpPost post = new HttpPost(client.getHttpServerUri() + bulkPath); - post.setEntity(new ByteArrayEntity(document.getBytes(StandardCharset.UTF_8), ContentType.APPLICATION_JSON)); - return client.executeRequest(post); + return client.postJson(bulkPath, document); }, parallelism, totalNumberOfRequests)); allRequests.addAll(AsyncActions.generate(() -> { @@ -90,7 +83,6 @@ public void testBulkAndCacheInvalidationMixed() throws Exception { // Make sure all requests start at the same time countDownLatch.countDown(); - Collections.shuffle(allRequests); AsyncActions.getAll(allRequests, 30, TimeUnit.SECONDS).forEach((response) -> { response.assertStatusCode(HttpStatus.SC_OK); }); }