diff --git a/integration-tests/src/main/java/org/apache/polaris/service/it/env/PolarisClient.java b/integration-tests/src/main/java/org/apache/polaris/service/it/env/PolarisClient.java index 1373c0d211..f3d60eeb16 100644 --- a/integration-tests/src/main/java/org/apache/polaris/service/it/env/PolarisClient.java +++ b/integration-tests/src/main/java/org/apache/polaris/service/it/env/PolarisClient.java @@ -18,42 +18,47 @@ */ package org.apache.polaris.service.it.env; -import static java.util.concurrent.TimeUnit.MINUTES; +import static org.apache.polaris.service.it.ext.PolarisServerManagerLoader.polarisServerManager; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategies; -import com.fasterxml.jackson.jakarta.rs.json.JacksonJsonProvider; import jakarta.ws.rs.client.Client; -import jakarta.ws.rs.client.ClientBuilder; +import java.util.Random; import org.apache.iceberg.rest.RESTSerializers; import org.apache.polaris.core.admin.model.PrincipalWithCredentials; public final class PolarisClient implements AutoCloseable { private final PolarisApiEndpoints endpoints; private final Client client; + // Use an alphanumeric ID for widest compatibility in HTTP and SQL. + // Use MAX_RADIX for shorter output. + private final String clientId = + Long.toString(Math.abs(new Random().nextLong()), Character.MAX_RADIX); private PolarisClient(PolarisApiEndpoints endpoints) { this.endpoints = endpoints; + this.client = polarisServerManager().createClient(); + } + + public static PolarisClient polarisClient(PolarisApiEndpoints endpoints) { + return new PolarisClient(endpoints); + } + + public static ObjectMapper buildObjectMapper() { ObjectMapper mapper = new ObjectMapper(); mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); mapper.setPropertyNamingStrategy(new PropertyNamingStrategies.KebabCaseStrategy()); RESTSerializers.registerAll(mapper); - - this.client = - ClientBuilder.newBuilder() - .readTimeout(5, MINUTES) - .connectTimeout(1, MINUTES) - .register(new JacksonJsonProvider(mapper)) - .build(); + return mapper; } - public static PolarisClient polarisClient(PolarisApiEndpoints endpoints) { - return new PolarisClient(endpoints); + public String newEntityName(String hint) { + return polarisServerManager().transformEntityName(hint + "_" + clientId); } public ManagementApi managementApi(String authToken) { diff --git a/integration-tests/src/main/java/org/apache/polaris/service/it/ext/PolarisIntegrationTestExtension.java b/integration-tests/src/main/java/org/apache/polaris/service/it/ext/PolarisIntegrationTestExtension.java index 1432fd44f8..6429aaa4f6 100644 --- a/integration-tests/src/main/java/org/apache/polaris/service/it/ext/PolarisIntegrationTestExtension.java +++ b/integration-tests/src/main/java/org/apache/polaris/service/it/ext/PolarisIntegrationTestExtension.java @@ -18,7 +18,8 @@ */ package org.apache.polaris.service.it.ext; -import java.util.ServiceLoader; +import static org.apache.polaris.service.it.ext.PolarisServerManagerLoader.polarisServerManager; + import org.apache.polaris.service.it.env.ClientCredentials; import org.apache.polaris.service.it.env.PolarisApiEndpoints; import org.apache.polaris.service.it.env.Server; @@ -34,11 +35,6 @@ public class PolarisIntegrationTestExtension implements ParameterResolver { private static final Namespace NAMESPACE = Namespace.create(PolarisIntegrationTestExtension.class); - private static final PolarisServerManager manager = - ServiceLoader.load(PolarisServerManager.class) - .findFirst() - .orElseThrow(() -> new IllegalStateException("PolarisServerManager not found")); - @Override public boolean supportsParameter( ParameterContext parameterContext, ExtensionContext extensionContext) @@ -66,7 +62,7 @@ private Env env(ExtensionContext context) { ExtensionContext classCtx = classContext(context); ExtensionContext.Store store = classCtx.getStore(NAMESPACE); return store.getOrComputeIfAbsent( - Env.class, (key) -> new Env(manager.serverForContext(classCtx)), Env.class); + Env.class, (key) -> new Env(polarisServerManager().serverForContext(classCtx)), Env.class); } private ExtensionContext classContext(ExtensionContext context) { diff --git a/integration-tests/src/main/java/org/apache/polaris/service/it/ext/PolarisServerManager.java b/integration-tests/src/main/java/org/apache/polaris/service/it/ext/PolarisServerManager.java index 3bdbb36883..79a3864595 100644 --- a/integration-tests/src/main/java/org/apache/polaris/service/it/ext/PolarisServerManager.java +++ b/integration-tests/src/main/java/org/apache/polaris/service/it/ext/PolarisServerManager.java @@ -18,6 +18,12 @@ */ package org.apache.polaris.service.it.ext; +import static java.util.concurrent.TimeUnit.MINUTES; +import static org.apache.polaris.service.it.env.PolarisClient.buildObjectMapper; + +import com.fasterxml.jackson.jakarta.rs.json.JacksonJsonProvider; +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.ClientBuilder; import org.apache.polaris.service.it.env.Server; import org.junit.jupiter.api.extension.ExtensionContext; @@ -31,4 +37,26 @@ public interface PolarisServerManager { * the argument to this call is closed. */ Server serverForContext(ExtensionContext context); + + /** Create a new HTTP client for accessing the server targeted by tests. */ + default Client createClient() { + return ClientBuilder.newBuilder() + .readTimeout(5, MINUTES) + .connectTimeout(1, MINUTES) + .register(new JacksonJsonProvider(buildObjectMapper())) + .build(); + } + + /** + * Transforms the name of an entity that tests need to create. Implementations may prepend of + * append text to the original name, but they should not alter the original name text or add any + * characters that have special meaning in Spark SQL, HTTP or Iceberg REST specifications. + * + *
This method will be called for all top-level entities (catalogs, principal, principal
+ * roles), but may not be called for secondary entities (such as catalog roles, namespaces,
+ * tables, etc.).
+ */
+ default String transformEntityName(String name) {
+ return name;
+ }
}
diff --git a/integration-tests/src/main/java/org/apache/polaris/service/it/ext/PolarisServerManagerLoader.java b/integration-tests/src/main/java/org/apache/polaris/service/it/ext/PolarisServerManagerLoader.java
new file mode 100644
index 0000000000..76879f880e
--- /dev/null
+++ b/integration-tests/src/main/java/org/apache/polaris/service/it/ext/PolarisServerManagerLoader.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.polaris.service.it.ext;
+
+import java.util.ServiceLoader;
+
+public final class PolarisServerManagerLoader {
+
+ private static final PolarisServerManager manager =
+ ServiceLoader.load(PolarisServerManager.class)
+ .findFirst()
+ .orElseThrow(() -> new IllegalStateException("PolarisServerManager not found"));
+
+ private PolarisServerManagerLoader() {}
+
+ public static PolarisServerManager polarisServerManager() {
+ return manager;
+ }
+}
diff --git a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisManagementServiceIntegrationTest.java b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisManagementServiceIntegrationTest.java
index bdf5739845..0a8d0705fb 100644
--- a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisManagementServiceIntegrationTest.java
+++ b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisManagementServiceIntegrationTest.java
@@ -190,7 +190,8 @@ public void testListCatalogs() {
@Test
public void testListCatalogsUnauthorized() {
- PrincipalWithCredentials principal = managementApi.createPrincipal("a_new_user");
+ PrincipalWithCredentials principal =
+ managementApi.createPrincipal(client.newEntityName("a_new_user"));
try (Response response = client.managementApi(principal).request("v1/catalogs").get()) {
assertThat(response).returns(Response.Status.FORBIDDEN.getStatusCode(), Response::getStatus);
}
@@ -480,7 +481,7 @@ public void testCreateExternalCatalog() {
.setStorageType(StorageConfigInfo.StorageTypeEnum.S3)
.setAllowedLocations(List.of("s3://my-old-bucket/path/to/data"))
.build();
- String catalogName = "my-external-catalog";
+ String catalogName = client.newEntityName("my-external-catalog");
String remoteUrl = "http://localhost:8080";
Catalog catalog =
ExternalCatalog.builder()
@@ -554,10 +555,11 @@ public void serialization() {
public void testCreateAndUpdateAzureCatalog() {
StorageConfigInfo storageConfig =
new AzureStorageConfigInfo("azure:tenantid:12345", StorageConfigInfo.StorageTypeEnum.AZURE);
+ String catalogName = client.newEntityName("myazurecatalog");
Catalog catalog =
PolarisCatalog.builder()
.setType(Catalog.TypeEnum.INTERNAL)
- .setName("myazurecatalog")
+ .setName(catalogName)
.setStorageConfigInfo(storageConfig)
.setProperties(new CatalogProperties("abfss://container1@acct1.dfs.core.windows.net/"))
.build();
@@ -567,11 +569,11 @@ public void testCreateAndUpdateAzureCatalog() {
// 200 successful GET after creation
Catalog fetchedCatalog;
- try (Response response = managementApi.request("v1/catalogs/myazurecatalog").get()) {
+ try (Response response = managementApi.request("v1/catalogs/" + catalogName).get()) {
assertThat(response).returns(Response.Status.OK.getStatusCode(), Response::getStatus);
fetchedCatalog = response.readEntity(Catalog.class);
- assertThat(fetchedCatalog.getName()).isEqualTo("myazurecatalog");
+ assertThat(fetchedCatalog.getName()).isEqualTo(catalogName);
assertThat(fetchedCatalog.getProperties().toMap())
.isEqualTo(
Map.of("default-base-location", "abfss://container1@acct1.dfs.core.windows.net/"));
@@ -586,7 +588,7 @@ public void testCreateAndUpdateAzureCatalog() {
Map.of("default-base-location", "abfss://newcontainer@acct1.dfs.core.windows.net/"),
modifiedStorageConfig);
try (Response response =
- managementApi.request("v1/catalogs/myazurecatalog").put(Entity.json(badUpdateRequest))) {
+ managementApi.request("v1/catalogs/" + catalogName).put(Entity.json(badUpdateRequest))) {
assertThat(response)
.returns(Response.Status.BAD_REQUEST.getStatusCode(), Response::getStatus);
ErrorResponse error = response.readEntity(ErrorResponse.class);
@@ -605,7 +607,7 @@ public void testCreateAndUpdateAzureCatalog() {
// 200 successful update
try (Response response =
- managementApi.request("v1/catalogs/myazurecatalog").put(Entity.json(updateRequest))) {
+ managementApi.request("v1/catalogs/" + catalogName).put(Entity.json(updateRequest))) {
assertThat(response).returns(Response.Status.OK.getStatusCode(), Response::getStatus);
fetchedCatalog = response.readEntity(Catalog.class);
@@ -615,7 +617,7 @@ public void testCreateAndUpdateAzureCatalog() {
}
// 204 Successful delete
- try (Response response = managementApi.request("v1/catalogs/myazurecatalog").delete()) {
+ try (Response response = managementApi.request("v1/catalogs/" + catalogName).delete()) {
assertThat(response).returns(Response.Status.NO_CONTENT.getStatusCode(), Response::getStatus);
}
}
@@ -625,10 +627,11 @@ public void testCreateListUpdateAndDeleteCatalog() {
StorageConfigInfo storageConfig =
new AwsStorageConfigInfo(
"arn:aws:iam::123456789011:role/role1", StorageConfigInfo.StorageTypeEnum.S3);
+ String catalogName = client.newEntityName("mycatalog");
Catalog catalog =
PolarisCatalog.builder()
.setType(Catalog.TypeEnum.INTERNAL)
- .setName("mycatalog")
+ .setName(catalogName)
.setStorageConfigInfo(storageConfig)
.setProperties(new CatalogProperties("s3://bucket1/"))
.build();
@@ -643,11 +646,11 @@ public void testCreateListUpdateAndDeleteCatalog() {
// 200 successful GET after creation
Catalog fetchedCatalog;
- try (Response response = managementApi.request("v1/catalogs/mycatalog").get()) {
+ try (Response response = managementApi.request("v1/catalogs/" + catalogName).get()) {
assertThat(response).returns(Response.Status.OK.getStatusCode(), Response::getStatus);
fetchedCatalog = response.readEntity(Catalog.class);
- assertThat(fetchedCatalog.getName()).isEqualTo("mycatalog");
+ assertThat(fetchedCatalog.getName()).isEqualTo(catalogName);
assertThat(fetchedCatalog.getProperties().toMap())
.isEqualTo(Map.of("default-base-location", "s3://bucket1/"));
assertThat(fetchedCatalog.getEntityVersion()).isGreaterThan(0);
@@ -661,7 +664,7 @@ public void testCreateListUpdateAndDeleteCatalog() {
.extracting(Catalogs::getCatalogs)
.asInstanceOf(InstanceOfAssertFactories.list(Catalog.class))
.filteredOn(cat -> !cat.getName().equalsIgnoreCase("ROOT"))
- .satisfiesExactly(cat -> assertThat(cat).returns("mycatalog", Catalog::getName));
+ .satisfiesExactly(cat -> assertThat(cat).returns(catalogName, Catalog::getName));
}
// Reject update of fields that can't be currently updated
@@ -674,7 +677,9 @@ public void testCreateListUpdateAndDeleteCatalog() {
Map.of("default-base-location", "s3://newbucket/"),
invalidModifiedStorageConfig);
try (Response response =
- managementApi.request("v1/catalogs/mycatalog").put(Entity.json(badUpdateRequest))) {
+ managementApi
+ .request("v1/catalogs/{cat}", Map.of("cat", catalogName))
+ .put(Entity.json(badUpdateRequest))) {
assertThat(response)
.returns(Response.Status.BAD_REQUEST.getStatusCode(), Response::getStatus);
ErrorResponse error = response.readEntity(ErrorResponse.class);
@@ -699,7 +704,9 @@ public void testCreateListUpdateAndDeleteCatalog() {
// 200 successful update
try (Response response =
- managementApi.request("v1/catalogs/mycatalog").put(Entity.json(updateRequest))) {
+ managementApi
+ .request("v1/catalogs/{cat}", Map.of("cat", catalogName))
+ .put(Entity.json(updateRequest))) {
assertThat(response).returns(Response.Status.OK.getStatusCode(), Response::getStatus);
fetchedCatalog = response.readEntity(Catalog.class);
@@ -711,7 +718,8 @@ public void testCreateListUpdateAndDeleteCatalog() {
}
// 200 GET after update should show new properties
- try (Response response = managementApi.request("v1/catalogs/mycatalog").get()) {
+ try (Response response =
+ managementApi.request("v1/catalogs/{cat}", Map.of("cat", catalogName)).get()) {
assertThat(response).returns(Response.Status.OK.getStatusCode(), Response::getStatus);
fetchedCatalog = response.readEntity(Catalog.class);
@@ -720,12 +728,14 @@ public void testCreateListUpdateAndDeleteCatalog() {
}
// 204 Successful delete
- try (Response response = managementApi.request("v1/catalogs/mycatalog").delete()) {
+ try (Response response =
+ managementApi.request("v1/catalogs/{cat}", Map.of("cat", catalogName)).delete()) {
assertThat(response).returns(Response.Status.NO_CONTENT.getStatusCode(), Response::getStatus);
}
// NOT_FOUND after deletion
- try (Response response = managementApi.request("v1/catalogs/mycatalog").get()) {
+ try (Response response =
+ managementApi.request("v1/catalogs/{cat}", Map.of("cat", catalogName)).get()) {
assertThat(response).returns(Response.Status.NOT_FOUND.getStatusCode(), Response::getStatus);
}
@@ -776,10 +786,11 @@ public void testGetCatalogInvalidName() {
@Test
public void testCatalogRoleInvalidName() {
+ String catalogName = client.newEntityName("mycatalog1");
Catalog catalog =
PolarisCatalog.builder()
.setType(Catalog.TypeEnum.INTERNAL)
- .setName("mycatalog1")
+ .setName(catalogName)
.setProperties(new CatalogProperties("s3://required/base/location"))
.setStorageConfigInfo(
new AwsStorageConfigInfo(
@@ -813,7 +824,8 @@ public void testCatalogRoleInvalidName() {
@Test
public void testListPrincipalsUnauthorized() {
- PrincipalWithCredentials principal = managementApi.createPrincipal("new_admin");
+ PrincipalWithCredentials principal =
+ managementApi.createPrincipal(client.newEntityName("new_admin"));
try (Response response = client.managementApi(principal).request("v1/principals").get()) {
assertThat(response).returns(Response.Status.FORBIDDEN.getStatusCode(), Response::getStatus);
}
@@ -1180,10 +1192,11 @@ public void testGetPrincipalRoleInvalidName() {
@Test
public void testCreateListUpdateAndDeleteCatalogRole() {
+ String catalogName = client.newEntityName("mycatalog1");
Catalog catalog =
PolarisCatalog.builder()
.setType(Catalog.TypeEnum.INTERNAL)
- .setName("mycatalog1")
+ .setName(catalogName)
.setProperties(new CatalogProperties("s3://required/base/location"))
.setStorageConfigInfo(
new AwsStorageConfigInfo(
@@ -1191,10 +1204,11 @@ public void testCreateListUpdateAndDeleteCatalogRole() {
.build();
managementApi.createCatalog(catalog);
+ String catalogName2 = client.newEntityName("mycatalog2");
Catalog catalog2 =
PolarisCatalog.builder()
.setType(Catalog.TypeEnum.INTERNAL)
- .setName("mycatalog2")
+ .setName(catalogName2)
.setStorageConfigInfo(
new AwsStorageConfigInfo(
"arn:aws:iam::012345678901:role/jdoe", StorageConfigInfo.StorageTypeEnum.S3))
@@ -1206,7 +1220,7 @@ public void testCreateListUpdateAndDeleteCatalogRole() {
new CatalogRole("mycatalogrole", Map.of("custom-tag", "foo"), 0L, 0L, 1);
try (Response response =
managementApi
- .request("v1/catalogs/mycatalog1/catalog-roles")
+ .request("v1/catalogs/{cat}/catalog-roles", Map.of("cat", catalogName))
.post(Entity.json(new CreateCatalogRoleRequest(catalogRole)))) {
assertThat(response).returns(Response.Status.CREATED.getStatusCode(), Response::getStatus);
@@ -1215,7 +1229,7 @@ public void testCreateListUpdateAndDeleteCatalogRole() {
// Second attempt to create the same entity should fail with CONFLICT.
try (Response response =
managementApi
- .request("v1/catalogs/mycatalog1/catalog-roles")
+ .request("v1/catalogs/{cat}/catalog-roles", Map.of("cat", catalogName))
.post(Entity.json(new CreateCatalogRoleRequest(catalogRole)))) {
assertThat(response).returns(Response.Status.CONFLICT.getStatusCode(), Response::getStatus);
@@ -1224,7 +1238,9 @@ public void testCreateListUpdateAndDeleteCatalogRole() {
// 200 successful GET after creation
CatalogRole fetchedCatalogRole;
try (Response response =
- managementApi.request("v1/catalogs/mycatalog1/catalog-roles/mycatalogrole").get()) {
+ managementApi
+ .request("v1/catalogs/{cat}/catalog-roles/mycatalogrole", Map.of("cat", catalogName))
+ .get()) {
assertThat(response).returns(Response.Status.OK.getStatusCode(), Response::getStatus);
fetchedCatalogRole = response.readEntity(CatalogRole.class);
@@ -1235,7 +1251,10 @@ public void testCreateListUpdateAndDeleteCatalogRole() {
}
// Should list the catalogRole.
- try (Response response = managementApi.request("v1/catalogs/mycatalog1/catalog-roles").get()) {
+ try (Response response =
+ managementApi
+ .request("v1/catalogs/{cat}/catalog-roles", Map.of("cat", catalogName))
+ .get()) {
assertThat(response)
.returns(Response.Status.OK.getStatusCode(), Response::getStatus)
@@ -1246,7 +1265,10 @@ public void testCreateListUpdateAndDeleteCatalogRole() {
}
// Empty list if listing in catalog2
- try (Response response = managementApi.request("v1/catalogs/mycatalog2/catalog-roles").get()) {
+ try (Response response =
+ managementApi
+ .request("v1/catalogs/{cat}/catalog-roles", Map.of("cat", catalogName2))
+ .get()) {
assertThat(response)
.returns(Response.Status.OK.getStatusCode(), Response::getStatus)
@@ -1268,7 +1290,7 @@ public void testCreateListUpdateAndDeleteCatalogRole() {
// 200 successful update
try (Response response =
managementApi
- .request("v1/catalogs/mycatalog1/catalog-roles/mycatalogrole")
+ .request("v1/catalogs/{cat}/catalog-roles/mycatalogrole", Map.of("cat", catalogName))
.put(Entity.json(updateRequest))) {
assertThat(response).returns(Response.Status.OK.getStatusCode(), Response::getStatus);
fetchedCatalogRole = response.readEntity(CatalogRole.class);
@@ -1278,7 +1300,9 @@ public void testCreateListUpdateAndDeleteCatalogRole() {
// 200 GET after update should show new properties
try (Response response =
- managementApi.request("v1/catalogs/mycatalog1/catalog-roles/mycatalogrole").get()) {
+ managementApi
+ .request("v1/catalogs/{cat}/catalog-roles/mycatalogrole", Map.of("cat", catalogName))
+ .get()) {
assertThat(response).returns(Response.Status.OK.getStatusCode(), Response::getStatus);
fetchedCatalogRole = response.readEntity(CatalogRole.class);
@@ -1287,20 +1311,27 @@ public void testCreateListUpdateAndDeleteCatalogRole() {
// 204 Successful delete
try (Response response =
- managementApi.request("v1/catalogs/mycatalog1/catalog-roles/mycatalogrole").delete()) {
+ managementApi
+ .request("v1/catalogs/{cat}/catalog-roles/mycatalogrole", Map.of("cat", catalogName))
+ .delete()) {
assertThat(response).returns(Response.Status.NO_CONTENT.getStatusCode(), Response::getStatus);
}
// NOT_FOUND after deletion
try (Response response =
- managementApi.request("v1/catalogs/mycatalog1/catalog-roles/mycatalogrole").get()) {
+ managementApi
+ .request("v1/catalogs/{cat}/catalog-roles/mycatalogrole", Map.of("cat", catalogName))
+ .get()) {
assertThat(response).returns(Response.Status.NOT_FOUND.getStatusCode(), Response::getStatus);
}
// Empty list
- try (Response response = managementApi.request("v1/catalogs/mycatalog1/catalog-roles").get()) {
+ try (Response response =
+ managementApi
+ .request("v1/catalogs/{cat}/catalog-roles", Map.of("cat", catalogName))
+ .get()) {
assertThat(response)
.returns(Response.Status.OK.getStatusCode(), Response::getStatus)
@@ -1311,14 +1342,14 @@ public void testCreateListUpdateAndDeleteCatalogRole() {
}
// 204 Successful delete mycatalog
- try (Response response = managementApi.request("v1/catalogs/mycatalog1").delete()) {
-
+ try (Response response =
+ managementApi.request("v1/catalogs/{cat}", Map.of("cat", catalogName)).delete()) {
assertThat(response).returns(Response.Status.NO_CONTENT.getStatusCode(), Response::getStatus);
}
// 204 Successful delete mycatalog2
- try (Response response = managementApi.request("v1/catalogs/mycatalog2").delete()) {
-
+ try (Response response =
+ managementApi.request("v1/catalogs/{cat}", Map.of("cat", catalogName2)).delete()) {
assertThat(response).returns(Response.Status.NO_CONTENT.getStatusCode(), Response::getStatus);
}
}
@@ -1326,7 +1357,7 @@ public void testCreateListUpdateAndDeleteCatalogRole() {
@Test
public void testAssignListAndRevokePrincipalRoles() {
// Create two Principals
- Principal principal1 = new Principal("myprincipal1");
+ Principal principal1 = new Principal(client.newEntityName("myprincipal1"));
try (Response response =
managementApi
.request("v1/principals")
@@ -1335,7 +1366,7 @@ public void testAssignListAndRevokePrincipalRoles() {
assertThat(response).returns(Response.Status.CREATED.getStatusCode(), Response::getStatus);
}
- Principal principal2 = new Principal("myprincipal2");
+ Principal principal2 = new Principal(client.newEntityName("myprincipal2"));
try (Response response =
managementApi
.request("v1/principals")
@@ -1345,21 +1376,24 @@ public void testAssignListAndRevokePrincipalRoles() {
}
// One PrincipalRole
- PrincipalRole principalRole = new PrincipalRole("myprincipalrole");
+ PrincipalRole principalRole = new PrincipalRole(client.newEntityName("myprincipalrole"));
managementApi.createPrincipalRole(principalRole);
// Assign the role to myprincipal1
try (Response response =
managementApi
- .request("v1/principals/myprincipal1/principal-roles")
+ .request(
+ "v1/principals/{prince}/principal-roles", Map.of("prince", principal1.getName()))
.put(Entity.json(principalRole))) {
-
assertThat(response).returns(Response.Status.CREATED.getStatusCode(), Response::getStatus);
}
// Should list myprincipalrole
try (Response response =
- managementApi.request("v1/principals/myprincipal1/principal-roles").get()) {
+ managementApi
+ .request(
+ "v1/principals/{prince}/principal-roles", Map.of("prince", principal1.getName()))
+ .get()) {
assertThat(response)
.returns(Response.Status.OK.getStatusCode(), Response::getStatus)
@@ -1368,12 +1402,14 @@ public void testAssignListAndRevokePrincipalRoles() {
.asInstanceOf(InstanceOfAssertFactories.list(PrincipalRole.class))
.hasSize(1)
.satisfiesExactly(
- pr -> assertThat(pr).returns("myprincipalrole", PrincipalRole::getName));
+ pr -> assertThat(pr).returns(principalRole.getName(), PrincipalRole::getName));
}
// Should list myprincipal1 if listing assignees of myprincipalrole
try (Response response =
- managementApi.request("v1/principal-roles/myprincipalrole/principals").get()) {
+ managementApi
+ .request("v1/principal-roles/{pr}/principals", Map.of("pr", principalRole.getName()))
+ .get()) {
assertThat(response)
.returns(Response.Status.OK.getStatusCode(), Response::getStatus)
@@ -1381,12 +1417,15 @@ public void testAssignListAndRevokePrincipalRoles() {
.extracting(Principals::getPrincipals)
.asInstanceOf(InstanceOfAssertFactories.list(Principal.class))
.hasSize(1)
- .satisfiesExactly(pr -> assertThat(pr).returns("myprincipal1", Principal::getName));
+ .satisfiesExactly(pr -> assertThat(pr).returns(principal1.getName(), Principal::getName));
}
// Empty list if listing in principal2
try (Response response =
- managementApi.request("v1/principals/myprincipal2/principal-roles").get()) {
+ managementApi
+ .request(
+ "v1/principals/{prince}/principal-roles", Map.of("prince", principal2.getName()))
+ .get()) {
assertThat(response)
.returns(Response.Status.OK.getStatusCode(), Response::getStatus)
@@ -1397,7 +1436,9 @@ public void testAssignListAndRevokePrincipalRoles() {
// 204 Successful revoke
try (Response response =
managementApi
- .request("v1/principals/myprincipal1/principal-roles/myprincipalrole")
+ .request(
+ "v1/principals/{prince}/principal-roles/{pr}",
+ Map.of("prince", principal1.getName(), "pr", principalRole.getName()))
.delete()) {
assertThat(response).returns(Response.Status.NO_CONTENT.getStatusCode(), Response::getStatus);
@@ -1405,7 +1446,10 @@ public void testAssignListAndRevokePrincipalRoles() {
// Empty list
try (Response response =
- managementApi.request("v1/principals/myprincipal1/principal-roles").get()) {
+ managementApi
+ .request(
+ "v1/principals/{prince}/principal-roles", Map.of("prince", principal1.getName()))
+ .get()) {
assertThat(response)
.returns(Response.Status.OK.getStatusCode(), Response::getStatus)
@@ -1413,8 +1457,9 @@ public void testAssignListAndRevokePrincipalRoles() {
.returns(List.of(), PrincipalRoles::getRoles);
}
try (Response response =
- managementApi.request("v1/principal-roles/myprincipalrole/principals").get()) {
-
+ managementApi
+ .request("v1/principal-roles/{pr}/principals", Map.of("pr", principalRole.getName()))
+ .get()) {
assertThat(response)
.returns(Response.Status.OK.getStatusCode(), Response::getStatus)
.extracting(r -> r.readEntity(Principals.class))
@@ -1422,20 +1467,27 @@ public void testAssignListAndRevokePrincipalRoles() {
}
// 204 Successful delete myprincipal1
- try (Response response = managementApi.request("v1/principals/myprincipal1").delete()) {
-
+ try (Response response =
+ managementApi
+ .request("v1/principals/{prince}", Map.of("prince", principal1.getName()))
+ .delete()) {
assertThat(response).returns(Response.Status.NO_CONTENT.getStatusCode(), Response::getStatus);
}
// 204 Successful delete myprincipal2
- try (Response response = managementApi.request("v1/principals/myprincipal2").delete()) {
+ try (Response response =
+ managementApi
+ .request("v1/principals/{prince}", Map.of("prince", principal2.getName()))
+ .delete()) {
assertThat(response).returns(Response.Status.NO_CONTENT.getStatusCode(), Response::getStatus);
}
// 204 Successful delete myprincipalrole
- try (Response response = managementApi.request("v1/principal-roles/myprincipalrole").delete()) {
-
+ try (Response response =
+ managementApi
+ .request("v1/principal-roles/{pr}", Map.of("pr", principalRole.getName()))
+ .delete()) {
assertThat(response).returns(Response.Status.NO_CONTENT.getStatusCode(), Response::getStatus);
}
}
@@ -1611,10 +1663,10 @@ public void testAssignListAndRevokeCatalogRoles() {
public void testCatalogAdminGrantAndRevokeCatalogRoles() {
// Create a PrincipalRole and a new catalog. Grant the catalog_admin role to the new principal
// role
- String principalRoleName = "mypr33";
+ String principalRoleName = client.newEntityName("mypr33");
managementApi.createPrincipalRole(principalRoleName);
- String catalogName = "myuniquetestcatalog";
+ String catalogName = client.newEntityName("myuniquetestcatalog");
Catalog catalog =
PolarisCatalog.builder()
.setType(Catalog.TypeEnum.INTERNAL)
@@ -1629,7 +1681,8 @@ public void testCatalogAdminGrantAndRevokeCatalogRoles() {
CatalogRole catalogAdminRole = managementApi.getCatalogRole(catalogName, "catalog_admin");
managementApi.grantCatalogRoleToPrincipalRole(principalRoleName, catalogName, catalogAdminRole);
- PrincipalWithCredentials catalogAdminPrincipal = managementApi.createPrincipal("principal1");
+ PrincipalWithCredentials catalogAdminPrincipal =
+ managementApi.createPrincipal(client.newEntityName("principal1"));
managementApi.assignPrincipalRole(
catalogAdminPrincipal.getPrincipal().getName(), principalRoleName);
@@ -1715,7 +1768,8 @@ public void testServiceAdminCanTransferCatalogAdmin() {
CatalogRole catalogAdminRole = managementApi.getCatalogRole(catalogName, "catalog_admin");
managementApi.grantCatalogRoleToPrincipalRole(principalRoleName, catalogName, catalogAdminRole);
- PrincipalWithCredentials catalogAdminPrincipal = managementApi.createPrincipal("principal1");
+ PrincipalWithCredentials catalogAdminPrincipal =
+ managementApi.createPrincipal(client.newEntityName("principal1"));
managementApi.assignPrincipalRole(
catalogAdminPrincipal.getPrincipal().getName(), principalRole1.getName());
@@ -1766,7 +1820,7 @@ public void testCatalogAdminGrantAndRevokeCatalogRolesFromWrongCatalog() {
managementApi.createPrincipalRole(principalRole1);
// create a catalog
- String catalogName = "mytestcatalog";
+ String catalogName = client.newEntityName("mytestcatalog");
Catalog catalog =
PolarisCatalog.builder()
.setType(Catalog.TypeEnum.INTERNAL)
@@ -1800,7 +1854,8 @@ public void testCatalogAdminGrantAndRevokeCatalogRolesFromWrongCatalog() {
managementApi.grantCatalogRoleToPrincipalRole(principalRoleName, catalogName, catalogAdminRole);
// Create a principal and grant the principal role to it
- PrincipalWithCredentials catalogAdminPrincipal = managementApi.createPrincipal("principal1");
+ PrincipalWithCredentials catalogAdminPrincipal =
+ managementApi.createPrincipal(client.newEntityName("principal1"));
managementApi.assignPrincipalRole(
catalogAdminPrincipal.getPrincipal().getName(), principalRole1.getName());
@@ -1830,7 +1885,7 @@ public void testTableManageAccessCanGrantAndRevokeFromCatalogRoles() {
managementApi.createPrincipalRole(principalRole1);
// create a catalog
- String catalogName = "mytablemanagecatalog";
+ String catalogName = client.newEntityName("mytablemanagecatalog");
Catalog catalog =
PolarisCatalog.builder()
.setType(Catalog.TypeEnum.INTERNAL)
@@ -1884,7 +1939,7 @@ public void testTableManageAccessCanGrantAndRevokeFromCatalogRoles() {
// Create a principal and grant the principal role to it
PrincipalWithCredentials catalogAdminPrincipal =
- managementApi.createPrincipal("ns_manage_access_user");
+ managementApi.createPrincipal(client.newEntityName("ns_manage_access_user"));
managementApi.assignPrincipalRole(
catalogAdminPrincipal.getPrincipal().getName(), principalRole1.getName());
@@ -2020,7 +2075,7 @@ public void testTokenInvalidPrincipalId() {
@Test
public void testNamespaceExistsStatus() {
// create a catalog
- String catalogName = "mytablemanagecatalog";
+ String catalogName = client.newEntityName("mytablemanagecatalog");
Catalog catalog =
PolarisCatalog.builder()
.setType(Catalog.TypeEnum.INTERNAL)
@@ -2046,7 +2101,7 @@ public void testNamespaceExistsStatus() {
@Test
public void testDropNamespaceStatus() {
// create a catalog
- String catalogName = "mytablemanagecatalog";
+ String catalogName = client.newEntityName("mytablemanagecatalog");
Catalog catalog =
PolarisCatalog.builder()
.setType(Catalog.TypeEnum.INTERNAL)
diff --git a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogIntegrationTest.java b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogIntegrationTest.java
index 7413cc8bdc..b202f1a85f 100644
--- a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogIntegrationTest.java
+++ b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogIntegrationTest.java
@@ -144,8 +144,8 @@ static void setup(PolarisApiEndpoints apiEndpoints, ClientCredentials credential
endpoints = apiEndpoints;
client = polarisClient(endpoints);
managementApi = client.managementApi(credentials);
- String principalName = "snowman-rest-" + UUID.randomUUID();
- principalRoleName = "rest-admin-" + UUID.randomUUID();
+ String principalName = client.newEntityName("snowman-rest");
+ principalRoleName = client.newEntityName("rest-admin");
principalCredentials = managementApi.createPrincipalWithRole(principalName, principalRoleName);
catalogApi = client.catalogApi(principalCredentials);
}
diff --git a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogViewIntegrationBase.java b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogViewIntegrationBase.java
index c7b1fcbe29..6516eb00c1 100644
--- a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogViewIntegrationBase.java
+++ b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisRestCatalogViewIntegrationBase.java
@@ -65,8 +65,8 @@ static void setup(PolarisApiEndpoints apiEndpoints, ClientCredentials credential
endpoints = apiEndpoints;
client = polarisClient(endpoints);
managementApi = client.managementApi(credentials);
- String principalName = "snowman-rest-" + UUID.randomUUID();
- principalRoleName = "rest-admin-" + UUID.randomUUID();
+ String principalName = client.newEntityName("snowman-rest");
+ principalRoleName = client.newEntityName("rest-admin");
principalCredentials = managementApi.createPrincipalWithRole(principalName, principalRoleName);
}
diff --git a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisSparkIntegrationTest.java b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisSparkIntegrationTest.java
index a5bc28c6b4..dc7c45ac05 100644
--- a/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisSparkIntegrationTest.java
+++ b/integration-tests/src/main/java/org/apache/polaris/service/it/test/PolarisSparkIntegrationTest.java
@@ -59,8 +59,6 @@
@ExtendWith(PolarisIntegrationTestExtension.class)
public class PolarisSparkIntegrationTest {
- public static final String CATALOG_NAME = "mycatalog";
- public static final String EXTERNAL_CATALOG_NAME = "external_catalog";
private static final S3MockContainer s3Container =
new S3MockContainer("3.11.0").withInitialBuckets("my-bucket,my-old-bucket");
private static SparkSession spark;
@@ -69,6 +67,8 @@ public class PolarisSparkIntegrationTest {
private ManagementApi managementApi;
private CatalogApi catalogApi;
private String sparkToken;
+ private String catalogName;
+ private String externalCatalogName;
@BeforeAll
public static void setup() throws IOException {
@@ -88,6 +88,9 @@ public void before(PolarisApiEndpoints apiEndpoints, ClientCredentials credentia
managementApi = client.managementApi(credentials);
catalogApi = client.catalogApi(credentials);
+ catalogName = client.newEntityName("spark_catalog");
+ externalCatalogName = client.newEntityName("spark_ext_catalog");
+
AwsStorageConfigInfo awsConfigModel =
AwsStorageConfigInfo.builder()
.setRoleArn("arn:aws:iam::123456789012:role/my-role")
@@ -118,7 +121,7 @@ public void before(PolarisApiEndpoints apiEndpoints, ClientCredentials credentia
Catalog catalog =
PolarisCatalog.builder()
.setType(Catalog.TypeEnum.INTERNAL)
- .setName(CATALOG_NAME)
+ .setName(catalogName)
.setProperties(props)
.setStorageConfigInfo(awsConfigModel)
.build();
@@ -147,7 +150,7 @@ public void before(PolarisApiEndpoints apiEndpoints, ClientCredentials credentia
Catalog externalCatalog =
ExternalCatalog.builder()
.setType(Catalog.TypeEnum.EXTERNAL)
- .setName(EXTERNAL_CATALOG_NAME)
+ .setName(externalCatalogName)
.setProperties(externalProps)
.setStorageConfigInfo(awsConfigModel)
.setRemoteUrl("http://dummy_url")
@@ -170,9 +173,9 @@ public void before(PolarisApiEndpoints apiEndpoints, ClientCredentials credentia
.config("spark.ui.showConsoleProgress", false)
.config("spark.ui.enabled", "false");
spark =
- withCatalog(withCatalog(sessionBuilder, CATALOG_NAME), EXTERNAL_CATALOG_NAME).getOrCreate();
+ withCatalog(withCatalog(sessionBuilder, catalogName), externalCatalogName).getOrCreate();
- onSpark("USE " + CATALOG_NAME);
+ onSpark("USE " + catalogName);
}
private SparkSession.Builder withCatalog(SparkSession.Builder builder, String catalogName) {
@@ -196,8 +199,8 @@ private SparkSession.Builder withCatalog(SparkSession.Builder builder, String ca
@AfterEach
public void after() throws Exception {
- cleanupCatalog(CATALOG_NAME);
- cleanupCatalog(EXTERNAL_CATALOG_NAME);
+ cleanupCatalog(catalogName);
+ cleanupCatalog(externalCatalogName);
try {
SparkSession.clearDefaultSession();
SparkSession.clearActiveSession();
@@ -252,7 +255,7 @@ public void testCreateAndUpdateExternalTable() {
long recordCount = onSpark("SELECT * FROM tb1").count();
assertThat(recordCount).isEqualTo(3);
- onSpark("USE " + EXTERNAL_CATALOG_NAME);
+ onSpark("USE " + externalCatalogName);
List