Fixes #2480 - Clean up create methods in entity resources tests (#2481)

This commit is contained in:
Suresh Srinivas 2022-01-27 16:29:43 -08:00 committed by GitHub
parent 3a6217a7e9
commit 10a94b265c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 1405 additions and 1801 deletions

View File

@ -13,6 +13,7 @@
package org.openmetadata.catalog.jdbi3;
import static org.openmetadata.catalog.util.EntityUtil.entityReferenceMatch;
import static org.openmetadata.catalog.util.EntityUtil.toBoolean;
import java.io.IOException;
@ -443,7 +444,7 @@ public class PolicyRepository extends EntityRepository<Policy> {
Entity.LOCATION,
Relationship.APPLIED_TO.ordinal());
}
recordChange("location", origPolicy.getLocation(), updatedPolicy.getLocation());
recordChange("location", origPolicy.getLocation(), updatedPolicy.getLocation(), true, entityReferenceMatch);
}
}
}

View File

@ -13,8 +13,9 @@
package org.openmetadata.catalog.security;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
import java.security.Principal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.json.JsonPatch;
@ -96,12 +97,8 @@ public final class SecurityUtil {
}
}
public static String getUserName(String principalName) {
return principalName == null ? null : principalName.split("[/@]")[0];
}
public static String getUserName(AuthenticationContext context) {
return context.getPrincipal() == null ? null : context.getPrincipal().getName();
return context.getPrincipal() == null ? null : context.getPrincipal().getName().split("[/@]")[0];
}
private static AuthenticationContext getAuthenticationContext(Principal principal) {
@ -111,11 +108,11 @@ public final class SecurityUtil {
}
public static Map<String, String> authHeaders(String username) {
Map<String, String> headers = new HashMap<>();
Builder<String, String> builder = ImmutableMap.builder();
if (username != null) {
headers.put(CatalogOpenIdAuthorizationRequestFilter.X_AUTH_PARAMS_EMAIL_HEADER, username);
builder.put(CatalogOpenIdAuthorizationRequestFilter.X_AUTH_PARAMS_EMAIL_HEADER, username);
}
return headers;
return builder.build();
}
public static Invocation.Builder addHeaders(WebTarget target, Map<String, String> headers) {

View File

@ -18,7 +18,7 @@ import lombok.extern.slf4j.Slf4j;
import org.openmetadata.catalog.util.ResultList;
@Slf4j
public abstract class EntityOperationsResourceTest<T> extends EntityResourceTest<T> {
public abstract class EntityOperationsResourceTest<T, K> extends EntityResourceTest<T, K> {
public EntityOperationsResourceTest(
String entityType,
Class<T> entityClass,

View File

@ -17,13 +17,12 @@ import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
import static javax.ws.rs.core.Response.Status.FORBIDDEN;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.openmetadata.catalog.security.SecurityUtil.authHeaders;
import static org.openmetadata.catalog.util.TestUtils.adminAuthHeaders;
import static org.openmetadata.catalog.util.TestUtils.ADMIN_AUTH_HEADERS;
import static org.openmetadata.catalog.util.TestUtils.TEST_AUTH_HEADERS;
import static org.openmetadata.catalog.util.TestUtils.assertListNotNull;
import static org.openmetadata.catalog.util.TestUtils.assertResponse;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
@ -34,15 +33,10 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
import org.openmetadata.catalog.Entity;
import org.openmetadata.catalog.api.data.CreateChart;
import org.openmetadata.catalog.api.services.CreateDashboardService;
import org.openmetadata.catalog.api.services.CreateDashboardService.DashboardServiceType;
import org.openmetadata.catalog.entity.data.Chart;
import org.openmetadata.catalog.entity.services.DashboardService;
import org.openmetadata.catalog.jdbi3.ChartRepository.ChartEntityInterface;
import org.openmetadata.catalog.jdbi3.DashboardServiceRepository.DashboardServiceEntityInterface;
import org.openmetadata.catalog.resources.EntityResourceTest;
import org.openmetadata.catalog.resources.charts.ChartResource.ChartList;
import org.openmetadata.catalog.resources.services.DashboardServiceResourceTest;
import org.openmetadata.catalog.type.ChartType;
import org.openmetadata.catalog.type.EntityReference;
import org.openmetadata.catalog.util.EntityInterface;
@ -50,9 +44,7 @@ import org.openmetadata.catalog.util.ResultList;
import org.openmetadata.catalog.util.TestUtils;
@Slf4j
public class ChartResourceTest extends EntityResourceTest<Chart> {
public static EntityReference SUPERSET_REFERENCE;
public static EntityReference LOOKER_REFERENCE;
public class ChartResourceTest extends EntityResourceTest<Chart, CreateChart> {
public ChartResourceTest() {
super(Entity.CHART, Chart.class, ChartList.class, "charts", ChartResource.FIELDS, true, true, true, true);
@ -61,53 +53,35 @@ public class ChartResourceTest extends EntityResourceTest<Chart> {
@BeforeAll
public void setup(TestInfo test) throws IOException, URISyntaxException {
super.setup(test);
CreateDashboardService createService =
new CreateDashboardService()
.withName("superset")
.withServiceType(DashboardServiceType.Superset)
.withDashboardUrl(new URI("http://localhost:0"));
DashboardService service = new DashboardServiceResourceTest().createEntity(createService, adminAuthHeaders());
SUPERSET_REFERENCE = new DashboardServiceEntityInterface(service).getEntityReference();
createService
.withName("looker")
.withServiceType(DashboardServiceType.Looker)
.withDashboardUrl(new URI("http://localhost:0"));
service = new DashboardServiceResourceTest().createEntity(createService, adminAuthHeaders());
LOOKER_REFERENCE = new DashboardServiceEntityInterface(service).getEntityReference();
}
@Test
void post_validCharts_as_admin_200_OK(TestInfo test) throws IOException {
// Create team with different optional fields
CreateChart create =
create(test)
.withService(
new EntityReference().withId(SUPERSET_REFERENCE.getId()).withType(SUPERSET_REFERENCE.getType()));
createAndCheckEntity(create, adminAuthHeaders());
CreateChart create = createRequest(test).withService(SUPERSET_REFERENCE);
createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
create.withName(getEntityName(test, 1)).withDescription("description");
Chart chart = createAndCheckEntity(create, adminAuthHeaders());
Chart chart = createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
String expectedFQN = SUPERSET_REFERENCE.getName() + "." + chart.getName();
assertEquals(expectedFQN, chart.getFullyQualifiedName());
}
@Test
void post_chartWithUserOwner_200_ok(TestInfo test) throws IOException {
createAndCheckEntity(create(test).withOwner(USER_OWNER1), adminAuthHeaders());
createAndCheckEntity(createRequest(test).withOwner(USER_OWNER1), ADMIN_AUTH_HEADERS);
}
@Test
void post_chartWithTeamOwner_200_ok(TestInfo test) throws IOException {
createAndCheckEntity(create(test).withOwner(TEAM_OWNER1).withDisplayName("chart1"), adminAuthHeaders());
createAndCheckEntity(createRequest(test).withOwner(TEAM_OWNER1).withDisplayName("chart1"), ADMIN_AUTH_HEADERS);
}
@Test
void post_chart_as_non_admin_401(TestInfo test) {
CreateChart create = create(test);
CreateChart create = createRequest(test);
assertResponse(
() -> createEntity(create, authHeaders("test@open-metadata.org")),
() -> createEntity(create, TEST_AUTH_HEADERS),
FORBIDDEN,
"Principal: CatalogPrincipal{name='test'} is not admin");
}
@ -116,7 +90,7 @@ public class ChartResourceTest extends EntityResourceTest<Chart> {
void post_chartWithoutRequiredFields_4xx(TestInfo test) {
// Service is required field
assertResponse(
() -> createEntity(create(test).withService(null), adminAuthHeaders()),
() -> createEntity(createRequest(test).withService(null), ADMIN_AUTH_HEADERS),
BAD_REQUEST,
"[service must not be null]");
}
@ -127,7 +101,7 @@ public class ChartResourceTest extends EntityResourceTest<Chart> {
// Create chart for each service and test APIs
for (EntityReference service : differentServices) {
createAndCheckEntity(create(test).withService(service), adminAuthHeaders());
createAndCheckEntity(createRequest(test).withService(service), ADMIN_AUTH_HEADERS);
// List charts by filtering on service name and ensure right charts in the response
Map<String, String> queryParams =
@ -136,7 +110,7 @@ public class ChartResourceTest extends EntityResourceTest<Chart> {
put("service", service.getName());
}
};
ResultList<Chart> list = listEntities(queryParams, adminAuthHeaders());
ResultList<Chart> list = listEntities(queryParams, ADMIN_AUTH_HEADERS);
for (Chart chart : list.getData()) {
assertEquals(service.getName(), chart.getService().getName());
}
@ -155,37 +129,29 @@ public class ChartResourceTest extends EntityResourceTest<Chart> {
String fields = "owner";
chart =
byName
? getEntityByName(chart.getFullyQualifiedName(), null, fields, adminAuthHeaders())
: getEntity(chart.getId(), fields, adminAuthHeaders());
? getEntityByName(chart.getFullyQualifiedName(), fields, ADMIN_AUTH_HEADERS)
: getEntity(chart.getId(), fields, ADMIN_AUTH_HEADERS);
assertListNotNull(chart.getOwner(), chart.getService(), chart.getServiceType());
}
private CreateChart create(TestInfo test) {
return create(getEntityName(test));
}
public CreateChart create(TestInfo test, int index) {
return create(getEntityName(test, index));
}
public CreateChart create(String name) {
return new CreateChart().withName(name).withService(SUPERSET_REFERENCE).withChartType(ChartType.Area);
@Override
public CreateChart createRequest(String name, String description, String displayName, EntityReference owner) {
return new CreateChart()
.withName(name)
.withDescription(description)
.withDisplayName(displayName)
.withOwner(owner)
.withService(SUPERSET_REFERENCE)
.withChartType(ChartType.Area);
}
@Override
public Object createRequest(String name, String description, String displayName, EntityReference owner) {
return create(name).withDescription(description).withDisplayName(displayName).withOwner(owner);
public EntityReference getContainer(CreateChart createRequest) {
return createRequest.getService();
}
@Override
public EntityReference getContainer(Object createRequest) throws URISyntaxException {
CreateChart createChart = (CreateChart) createRequest;
return createChart.getService();
}
@Override
public void validateCreatedEntity(Chart chart, Object request, Map<String, String> authHeaders) {
CreateChart createRequest = (CreateChart) request;
public void validateCreatedEntity(Chart chart, CreateChart createRequest, Map<String, String> authHeaders) {
validateCommonEntityFields(
getEntityInterface(chart),
createRequest.getDescription(),
@ -196,7 +162,7 @@ public class ChartResourceTest extends EntityResourceTest<Chart> {
}
@Override
public void validateUpdatedEntity(Chart updatedEntity, Object request, Map<String, String> authHeaders) {
public void validateUpdatedEntity(Chart updatedEntity, CreateChart request, Map<String, String> authHeaders) {
validateCreatedEntity(updatedEntity, request, authHeaders);
}

View File

@ -22,12 +22,13 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.openmetadata.catalog.exception.CatalogExceptionMessage.invalidServiceEntity;
import static org.openmetadata.catalog.security.SecurityUtil.authHeaders;
import static org.openmetadata.catalog.util.TestUtils.ADMIN_AUTH_HEADERS;
import static org.openmetadata.catalog.util.TestUtils.TEST_AUTH_HEADERS;
import static org.openmetadata.catalog.util.TestUtils.UpdateType.MINOR_UPDATE;
import static org.openmetadata.catalog.util.TestUtils.adminAuthHeaders;
import static org.openmetadata.catalog.util.TestUtils.assertListNotNull;
import static org.openmetadata.catalog.util.TestUtils.assertListNull;
import static org.openmetadata.catalog.util.TestUtils.assertResponse;
import static org.openmetadata.catalog.util.TestUtils.assertResponseContains;
import java.io.IOException;
import java.net.URISyntaxException;
@ -43,20 +44,11 @@ import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
import org.openmetadata.catalog.Entity;
import org.openmetadata.catalog.api.data.CreateChart;
import org.openmetadata.catalog.api.data.CreateDashboard;
import org.openmetadata.catalog.api.services.CreateDashboardService;
import org.openmetadata.catalog.api.services.CreateDashboardService.DashboardServiceType;
import org.openmetadata.catalog.entity.data.Chart;
import org.openmetadata.catalog.entity.data.Dashboard;
import org.openmetadata.catalog.entity.services.DashboardService;
import org.openmetadata.catalog.jdbi3.ChartRepository.ChartEntityInterface;
import org.openmetadata.catalog.jdbi3.DashboardRepository.DashboardEntityInterface;
import org.openmetadata.catalog.jdbi3.DashboardServiceRepository.DashboardServiceEntityInterface;
import org.openmetadata.catalog.resources.EntityResourceTest;
import org.openmetadata.catalog.resources.charts.ChartResourceTest;
import org.openmetadata.catalog.resources.dashboards.DashboardResource.DashboardList;
import org.openmetadata.catalog.resources.services.DashboardServiceResourceTest;
import org.openmetadata.catalog.type.ChangeDescription;
import org.openmetadata.catalog.type.EntityReference;
import org.openmetadata.catalog.type.FieldChange;
@ -66,11 +58,8 @@ import org.openmetadata.catalog.util.ResultList;
import org.openmetadata.catalog.util.TestUtils;
@Slf4j
public class DashboardResourceTest extends EntityResourceTest<Dashboard> {
public static EntityReference SUPERSET_REFERENCE;
public static EntityReference LOOKER_REFERENCE;
public class DashboardResourceTest extends EntityResourceTest<Dashboard, CreateDashboard> {
public static EntityReference SUPERSET_INVALID_SERVICE_REFERENCE;
public static List<EntityReference> CHART_REFERENCES;
public DashboardResourceTest() {
super(
@ -89,79 +78,59 @@ public class DashboardResourceTest extends EntityResourceTest<Dashboard> {
public void setup(TestInfo test) throws IOException, URISyntaxException {
super.setup(test);
CreateDashboardService createService =
new CreateDashboardService()
.withName("superset")
.withServiceType(DashboardServiceType.Superset)
.withDashboardUrl(TestUtils.DASHBOARD_URL);
DashboardService service = new DashboardServiceResourceTest().createEntity(createService, adminAuthHeaders());
SUPERSET_REFERENCE = new DashboardServiceEntityInterface(service).getEntityReference();
SUPERSET_INVALID_SERVICE_REFERENCE =
new EntityReference()
.withName("invalid_superset_service")
.withId(SUPERSET_REFERENCE.getId())
.withType("DashboardService1");
createService.withName("looker").withServiceType(DashboardServiceType.Looker);
service = new DashboardServiceResourceTest().createEntity(createService, adminAuthHeaders());
LOOKER_REFERENCE = new DashboardServiceEntityInterface(service).getEntityReference();
CHART_REFERENCES = new ArrayList<>();
ChartResourceTest chartResourceTest = new ChartResourceTest();
for (int i = 0; i < 3; i++) {
CreateChart createChart = chartResourceTest.create(test, i).withService(SUPERSET_REFERENCE);
Chart chart = chartResourceTest.createEntity(createChart, adminAuthHeaders());
CHART_REFERENCES.add(new ChartEntityInterface(chart).getEntityReference());
}
}
@Test
void post_validDashboards_as_admin_200_OK(TestInfo test) throws IOException {
// Create team with different optional fields
CreateDashboard create = create(test);
createAndCheckEntity(create, adminAuthHeaders());
CreateDashboard create = createRequest(test);
createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
create.withName(getEntityName(test, 1)).withDescription("description");
createAndCheckEntity(create, adminAuthHeaders());
createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
}
@Test
void post_DashboardWithUserOwner_200_ok(TestInfo test) throws IOException {
createAndCheckEntity(create(test).withOwner(USER_OWNER1), adminAuthHeaders());
createAndCheckEntity(createRequest(test).withOwner(USER_OWNER1), ADMIN_AUTH_HEADERS);
}
@Test
void post_DashboardWithTeamOwner_200_ok(TestInfo test) throws IOException {
createAndCheckEntity(create(test).withOwner(TEAM_OWNER1).withDisplayName("Dashboard1"), adminAuthHeaders());
createAndCheckEntity(createRequest(test).withOwner(TEAM_OWNER1).withDisplayName("Dashboard1"), ADMIN_AUTH_HEADERS);
}
@Test
void post_DashboardWithCharts_200_ok(TestInfo test) throws IOException {
createAndCheckEntity(create(test).withCharts(CHART_REFERENCES), adminAuthHeaders());
createAndCheckEntity(createRequest(test).withCharts(CHART_REFERENCES), ADMIN_AUTH_HEADERS);
}
@Test
void post_Dashboard_as_non_admin_401(TestInfo test) {
CreateDashboard create = create(test);
CreateDashboard create = createRequest(test);
assertResponse(
() -> createDashboard(create, authHeaders("test@open-metadata.org")),
() -> createEntity(create, TEST_AUTH_HEADERS),
FORBIDDEN,
"Principal: CatalogPrincipal{name='test'} is not admin");
}
@Test
void post_DashboardWithoutRequiredService_4xx(TestInfo test) {
CreateDashboard create = create(test).withService(null);
TestUtils.assertResponseContains(
() -> createDashboard(create, adminAuthHeaders()), BAD_REQUEST, "service must not be null");
CreateDashboard create = createRequest(test).withService(null);
assertResponseContains(() -> createEntity(create, ADMIN_AUTH_HEADERS), BAD_REQUEST, "service must not be null");
}
@Test
void post_DashboardWithInvalidService_4xx(TestInfo test) {
CreateDashboard create = create(test).withService(SUPERSET_INVALID_SERVICE_REFERENCE);
CreateDashboard create = createRequest(test).withService(SUPERSET_INVALID_SERVICE_REFERENCE);
HttpResponseException exception =
assertThrows(HttpResponseException.class, () -> createDashboard(create, adminAuthHeaders()));
TestUtils.assertResponseContains(
assertThrows(HttpResponseException.class, () -> createEntity(create, ADMIN_AUTH_HEADERS));
assertResponseContains(
exception, BAD_REQUEST, invalidServiceEntity(SUPERSET_INVALID_SERVICE_REFERENCE.getType(), Entity.DASHBOARD));
}
@ -172,8 +141,8 @@ public class DashboardResourceTest extends EntityResourceTest<Dashboard> {
// Create Dashboard for each service and test APIs
for (EntityReference service : differentServices) {
createAndCheckEntity(
create(test).withService(new EntityReference().withId(service.getId()).withType(service.getType())),
adminAuthHeaders());
createRequest(test).withService(new EntityReference().withId(service.getId()).withType(service.getType())),
ADMIN_AUTH_HEADERS);
// List Dashboards by filtering on service name and ensure right Dashboards in the response
Map<String, String> queryParams =
new HashMap<>() {
@ -181,7 +150,7 @@ public class DashboardResourceTest extends EntityResourceTest<Dashboard> {
put("service", service.getName());
}
};
ResultList<Dashboard> list = listEntities(queryParams, adminAuthHeaders());
ResultList<Dashboard> list = listEntities(queryParams, ADMIN_AUTH_HEADERS);
for (Dashboard db : list.getData()) {
assertEquals(service.getName(), db.getService().getName());
String expectedFQN = service.getName() + "." + db.getName();
@ -192,8 +161,8 @@ public class DashboardResourceTest extends EntityResourceTest<Dashboard> {
@Test
void put_DashboardChartsUpdate_200(TestInfo test) throws IOException {
CreateDashboard request = create(test).withService(SUPERSET_REFERENCE).withDescription(null);
Dashboard dashboard = createAndCheckEntity(request, adminAuthHeaders());
CreateDashboard request = createRequest(test).withDescription(null).withCharts(null);
Dashboard dashboard = createAndCheckEntity(request, ADMIN_AUTH_HEADERS);
// Add description, and charts
List<FieldChange> fields = new ArrayList<>();
@ -203,28 +172,28 @@ public class DashboardResourceTest extends EntityResourceTest<Dashboard> {
updateAndCheckEntity(
request.withDescription("newDescription").withCharts(CHART_REFERENCES),
OK,
adminAuthHeaders(),
ADMIN_AUTH_HEADERS,
MINOR_UPDATE,
change);
}
@Test
void put_AddRemoveDashboardChartsUpdate_200(TestInfo test) throws IOException {
CreateDashboard request = create(test).withService(SUPERSET_REFERENCE).withDescription(null);
Dashboard dashboard = createAndCheckEntity(request, adminAuthHeaders());
CreateDashboard request = createRequest(test).withDescription(null).withCharts(null);
Dashboard dashboard = createAndCheckEntity(request, ADMIN_AUTH_HEADERS);
// Add charts
FieldChange charts = new FieldChange().withName("charts").withNewValue(CHART_REFERENCES);
ChangeDescription change = getChangeDescription(dashboard.getVersion()).withFieldsAdded(singletonList(charts));
dashboard =
updateAndCheckEntity(request.withCharts(CHART_REFERENCES), OK, adminAuthHeaders(), MINOR_UPDATE, change);
updateAndCheckEntity(request.withCharts(CHART_REFERENCES), OK, ADMIN_AUTH_HEADERS, MINOR_UPDATE, change);
validateDashboardCharts(dashboard, CHART_REFERENCES);
// remove a chart
charts = new FieldChange().withName("charts").withOldValue(List.of(CHART_REFERENCES.get(0)));
CHART_REFERENCES.remove(0);
change = getChangeDescription(dashboard.getVersion()).withFieldsDeleted(singletonList(charts));
updateAndCheckEntity(request.withCharts(CHART_REFERENCES), OK, adminAuthHeaders(), MINOR_UPDATE, change);
updateAndCheckEntity(request.withCharts(CHART_REFERENCES), OK, ADMIN_AUTH_HEADERS, MINOR_UPDATE, change);
}
@Test
@ -232,11 +201,6 @@ public class DashboardResourceTest extends EntityResourceTest<Dashboard> {
// TODO
}
public Dashboard createDashboard(CreateDashboard create, Map<String, String> authHeaders)
throws HttpResponseException {
return TestUtils.post(getResource("dashboards"), create, Dashboard.class, authHeaders);
}
/** Validate returned fields GET .../dashboards/{id}?fields="..." or GET .../dashboards/name/{fqn}?fields="..." */
@Override
public void validateGetWithDifferentFields(Dashboard dashboard, boolean byName) throws HttpResponseException {
@ -244,8 +208,8 @@ public class DashboardResourceTest extends EntityResourceTest<Dashboard> {
String fields = "owner";
dashboard =
byName
? getEntityByName(dashboard.getFullyQualifiedName(), null, fields, adminAuthHeaders())
: getEntity(dashboard.getId(), fields, adminAuthHeaders());
? getEntityByName(dashboard.getFullyQualifiedName(), fields, ADMIN_AUTH_HEADERS)
: getEntity(dashboard.getId(), fields, ADMIN_AUTH_HEADERS);
// We always return the service
assertListNotNull(dashboard.getOwner(), dashboard.getService(), dashboard.getServiceType());
assertListNull(dashboard.getCharts(), dashboard.getUsageSummary());
@ -254,8 +218,8 @@ public class DashboardResourceTest extends EntityResourceTest<Dashboard> {
fields = "owner,charts,usageSummary";
dashboard =
byName
? getEntityByName(dashboard.getFullyQualifiedName(), null, fields, adminAuthHeaders())
: getEntity(dashboard.getId(), fields, adminAuthHeaders());
? getEntityByName(dashboard.getFullyQualifiedName(), fields, ADMIN_AUTH_HEADERS)
: getEntity(dashboard.getId(), fields, ADMIN_AUTH_HEADERS);
assertListNotNull(
dashboard.getOwner(),
dashboard.getService(),
@ -283,33 +247,25 @@ public class DashboardResourceTest extends EntityResourceTest<Dashboard> {
}
}
public CreateDashboard create(TestInfo test) {
return create(getEntityName(test));
}
public CreateDashboard create(String name) {
return new CreateDashboard().withName(name).withService(SUPERSET_REFERENCE);
}
@Override
public Object createRequest(String name, String description, String displayName, EntityReference owner) {
return create(name)
public CreateDashboard createRequest(String name, String description, String displayName, EntityReference owner) {
return new CreateDashboard()
.withName(name)
.withService(SUPERSET_REFERENCE)
.withCharts(CHART_REFERENCES)
.withDescription(description)
.withDisplayName(displayName)
.withOwner(owner)
.withCharts(CHART_REFERENCES);
.withOwner(owner);
}
@Override
public EntityReference getContainer(Object createRequest) throws URISyntaxException {
CreateDashboard createDashboard = (CreateDashboard) createRequest;
return createDashboard.getService();
public EntityReference getContainer(CreateDashboard createRequest) {
return createRequest.getService();
}
@Override
public void validateCreatedEntity(Dashboard dashboard, Object request, Map<String, String> authHeaders)
public void validateCreatedEntity(Dashboard dashboard, CreateDashboard createRequest, Map<String, String> authHeaders)
throws HttpResponseException {
CreateDashboard createRequest = (CreateDashboard) request;
validateCommonEntityFields(
getEntityInterface(dashboard),
createRequest.getDescription(),
@ -322,7 +278,7 @@ public class DashboardResourceTest extends EntityResourceTest<Dashboard> {
}
@Override
public void validateUpdatedEntity(Dashboard dashboard, Object request, Map<String, String> authHeaders)
public void validateUpdatedEntity(Dashboard dashboard, CreateDashboard request, Map<String, String> authHeaders)
throws HttpResponseException {
validateCreatedEntity(dashboard, request, authHeaders);
}
@ -341,6 +297,7 @@ public class DashboardResourceTest extends EntityResourceTest<Dashboard> {
return;
}
if (fieldName.contains("charts")) {
@SuppressWarnings("unchecked")
List<EntityReference> expectedRefs = (List<EntityReference>) expected;
List<EntityReference> actualRefs = JsonUtils.readObjects(actual.toString(), EntityReference.class);
assertEquals(expectedRefs, actualRefs);

View File

@ -18,8 +18,8 @@ import static javax.ws.rs.core.Response.Status.FORBIDDEN;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.openmetadata.catalog.security.SecurityUtil.authHeaders;
import static org.openmetadata.catalog.util.TestUtils.adminAuthHeaders;
import static org.openmetadata.catalog.util.TestUtils.ADMIN_AUTH_HEADERS;
import static org.openmetadata.catalog.util.TestUtils.TEST_AUTH_HEADERS;
import static org.openmetadata.catalog.util.TestUtils.assertListNotNull;
import static org.openmetadata.catalog.util.TestUtils.assertListNull;
import static org.openmetadata.catalog.util.TestUtils.assertResponse;
@ -47,7 +47,7 @@ import org.openmetadata.catalog.util.TestUtils;
@Slf4j
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class DatabaseResourceTest extends EntityResourceTest<Database> {
public class DatabaseResourceTest extends EntityResourceTest<Database, CreateDatabase> {
public DatabaseResourceTest() {
super(
Entity.DATABASE,
@ -69,46 +69,46 @@ public class DatabaseResourceTest extends EntityResourceTest<Database> {
@Test
void post_validDatabases_as_admin_200_OK(TestInfo test) throws IOException {
// Create team with different optional fields
CreateDatabase create = create(test);
createAndCheckEntity(create, adminAuthHeaders());
CreateDatabase create = createRequest(test);
createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
create.withName(getEntityName(test, 1)).withDescription("description");
createAndCheckEntity(create, adminAuthHeaders());
createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
}
@Test
void post_databaseFQN_as_admin_200_OK(TestInfo test) throws IOException {
// Create team with different optional fields
CreateDatabase create = create(test);
CreateDatabase create = createRequest(test);
create.setService(new EntityReference().withId(SNOWFLAKE_REFERENCE.getId()).withType("databaseService"));
Database db = createAndCheckEntity(create, adminAuthHeaders());
Database db = createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
String expectedFQN = SNOWFLAKE_REFERENCE.getName() + "." + create.getName();
assertEquals(expectedFQN, db.getFullyQualifiedName());
}
@Test
void post_databaseWithUserOwner_200_ok(TestInfo test) throws IOException {
createAndCheckEntity(create(test).withOwner(USER_OWNER1), adminAuthHeaders());
createAndCheckEntity(createRequest(test).withOwner(USER_OWNER1), ADMIN_AUTH_HEADERS);
}
@Test
void post_databaseWithTeamOwner_200_ok(TestInfo test) throws IOException {
createAndCheckEntity(create(test).withOwner(TEAM_OWNER1), adminAuthHeaders());
createAndCheckEntity(createRequest(test).withOwner(TEAM_OWNER1), ADMIN_AUTH_HEADERS);
}
@Test
void post_database_as_non_admin_401(TestInfo test) {
CreateDatabase create = create(test);
CreateDatabase create = createRequest(test);
HttpResponseException exception =
assertThrows(HttpResponseException.class, () -> createDatabase(create, authHeaders("test@open-metadata.org")));
assertThrows(HttpResponseException.class, () -> createEntity(create, TEST_AUTH_HEADERS));
assertResponse(exception, FORBIDDEN, "Principal: CatalogPrincipal{name='test'} is not admin");
}
@Test
void post_databaseWithoutRequiredService_4xx(TestInfo test) {
CreateDatabase create = create(test).withService(null);
CreateDatabase create = createRequest(test).withService(null);
HttpResponseException exception =
assertThrows(HttpResponseException.class, () -> createDatabase(create, adminAuthHeaders()));
assertThrows(HttpResponseException.class, () -> createEntity(create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponseContains(exception, BAD_REQUEST, "service must not be null");
}
@ -120,7 +120,7 @@ public class DatabaseResourceTest extends EntityResourceTest<Database> {
// Create database for each service and test APIs
for (EntityReference service : differentServices) {
createAndCheckEntity(create(test).withService(service), adminAuthHeaders());
createAndCheckEntity(createRequest(test).withService(service), ADMIN_AUTH_HEADERS);
// List databases by filtering on service name and ensure right databases in the response
Map<String, String> queryParams =
@ -129,7 +129,7 @@ public class DatabaseResourceTest extends EntityResourceTest<Database> {
put("service", service.getName());
}
};
ResultList<Database> list = listEntities(queryParams, adminAuthHeaders());
ResultList<Database> list = listEntities(queryParams, ADMIN_AUTH_HEADERS);
for (Database db : list.getData()) {
assertEquals(service.getName(), db.getService().getName());
}
@ -141,11 +141,6 @@ public class DatabaseResourceTest extends EntityResourceTest<Database> {
// TODO
}
public static Database createDatabase(CreateDatabase create, Map<String, String> authHeaders)
throws HttpResponseException {
return TestUtils.post(getResource("databases"), create, Database.class, authHeaders);
}
/** Validate returned fields GET .../databases/{id}?fields="..." or GET .../databases/name/{fqn}?fields="..." */
@Override
public void validateGetWithDifferentFields(Database database, boolean byName) throws HttpResponseException {
@ -153,8 +148,8 @@ public class DatabaseResourceTest extends EntityResourceTest<Database> {
String fields = "owner";
database =
byName
? getEntityByName(database.getFullyQualifiedName(), null, fields, adminAuthHeaders())
: getEntity(database.getId(), fields, adminAuthHeaders());
? getEntityByName(database.getFullyQualifiedName(), fields, ADMIN_AUTH_HEADERS)
: getEntity(database.getId(), fields, ADMIN_AUTH_HEADERS);
assertListNotNull(database.getOwner(), database.getService(), database.getServiceType());
assertListNull(database.getTables(), database.getUsageSummary());
@ -162,8 +157,8 @@ public class DatabaseResourceTest extends EntityResourceTest<Database> {
fields = "owner,tables,usageSummary";
database =
byName
? getEntityByName(database.getFullyQualifiedName(), null, fields, adminAuthHeaders())
: getEntity(database.getId(), fields, adminAuthHeaders());
? getEntityByName(database.getFullyQualifiedName(), fields, ADMIN_AUTH_HEADERS)
: getEntity(database.getId(), fields, ADMIN_AUTH_HEADERS);
assertListNotNull(
database.getOwner(),
database.getService(),
@ -173,28 +168,22 @@ public class DatabaseResourceTest extends EntityResourceTest<Database> {
TestUtils.validateEntityReference(database.getTables());
}
public CreateDatabase create(TestInfo test) {
return create(getEntityName(test));
}
private CreateDatabase create(String name) {
return new CreateDatabase().withName(name).withService(SNOWFLAKE_REFERENCE);
@Override
public CreateDatabase createRequest(String name, String description, String displayName, EntityReference owner) {
return new CreateDatabase()
.withName(name)
.withDescription(description)
.withOwner(owner)
.withService(SNOWFLAKE_REFERENCE);
}
@Override
public Object createRequest(String name, String description, String displayName, EntityReference owner) {
return create(name).withDescription(description).withOwner(owner);
public EntityReference getContainer(CreateDatabase createRequest) {
return createRequest.getService();
}
@Override
public EntityReference getContainer(Object createRequest) throws URISyntaxException {
CreateDatabase createDatabase = (CreateDatabase) createRequest;
return createDatabase.getService();
}
@Override
public void validateCreatedEntity(Database database, Object request, Map<String, String> authHeaders) {
CreateDatabase createRequest = (CreateDatabase) request;
public void validateCreatedEntity(Database database, CreateDatabase createRequest, Map<String, String> authHeaders) {
validateCommonEntityFields(
getEntityInterface(database),
createRequest.getDescription(),
@ -207,7 +196,7 @@ public class DatabaseResourceTest extends EntityResourceTest<Database> {
}
@Override
public void validateUpdatedEntity(Database updatedEntity, Object request, Map<String, String> authHeaders) {
public void validateUpdatedEntity(Database updatedEntity, CreateDatabase request, Map<String, String> authHeaders) {
validateCreatedEntity(updatedEntity, request, authHeaders);
}

View File

@ -16,11 +16,10 @@ package org.openmetadata.catalog.resources.events;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.openmetadata.catalog.util.TestUtils.adminAuthHeaders;
import static org.openmetadata.catalog.util.TestUtils.ADMIN_AUTH_HEADERS;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@ -53,7 +52,7 @@ import org.openmetadata.catalog.util.TestUtils;
import org.openmetadata.catalog.util.TestUtils.UpdateType;
@Slf4j
public class WebhookResourceTest extends EntityResourceTest<Webhook> {
public class WebhookResourceTest extends EntityResourceTest<Webhook, CreateWebhook> {
public static final List<EventFilter> ALL_EVENTS_FILTER;
static {
@ -70,7 +69,7 @@ public class WebhookResourceTest extends EntityResourceTest<Webhook> {
}
@Test
void post_webhookEnabledStateChange(TestInfo test) throws URISyntaxException, IOException, InterruptedException {
void post_webhookEnabledStateChange(TestInfo test) throws IOException, InterruptedException {
//
// Create webhook in disabled state. It will not start webhook publisher
//
@ -78,9 +77,9 @@ public class WebhookResourceTest extends EntityResourceTest<Webhook> {
LOG.info("creating webhook in disabled state");
String uri = "http://localhost:" + APP.getLocalPort() + "/api/v1/test/webhook/" + webhookName;
CreateWebhook create = createRequest(webhookName, "", "", null).withEnabled(false).withEndpoint(URI.create(uri));
Webhook webhook = createAndCheckEntity(create, adminAuthHeaders());
Webhook webhook = createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
assertEquals(Status.NOT_STARTED, webhook.getStatus());
Webhook getWebhook = getEntity(webhook.getId(), adminAuthHeaders());
Webhook getWebhook = getEntity(webhook.getId(), ADMIN_AUTH_HEADERS);
assertEquals(Status.NOT_STARTED, getWebhook.getStatus());
EventDetails details = webhookCallbackResource.getEventDetails(webhookName);
assertNull(details);
@ -97,9 +96,9 @@ public class WebhookResourceTest extends EntityResourceTest<Webhook> {
change.getFieldsUpdated().add(new FieldChange().withName("batchSize").withOldValue(10).withNewValue(50));
create.withEnabled(true).withBatchSize(50);
webhook = updateAndCheckEntity(create, Response.Status.OK, adminAuthHeaders(), UpdateType.MINOR_UPDATE, change);
webhook = updateAndCheckEntity(create, Response.Status.OK, ADMIN_AUTH_HEADERS, UpdateType.MINOR_UPDATE, change);
assertEquals(Status.STARTED, webhook.getStatus());
getWebhook = getEntity(webhook.getId(), adminAuthHeaders());
getWebhook = getEntity(webhook.getId(), ADMIN_AUTH_HEADERS);
assertEquals(Status.STARTED, getWebhook.getStatus());
// Ensure the call back notification has started
@ -123,11 +122,11 @@ public class WebhookResourceTest extends EntityResourceTest<Webhook> {
.add(new FieldChange().withName("status").withOldValue(Status.STARTED).withNewValue(Status.NOT_STARTED));
// Disabled webhook state is NOT_STARTED
getWebhook = updateAndCheckEntity(create, Response.Status.OK, adminAuthHeaders(), UpdateType.MINOR_UPDATE, change);
getWebhook = updateAndCheckEntity(create, Response.Status.OK, ADMIN_AUTH_HEADERS, UpdateType.MINOR_UPDATE, change);
assertEquals(Status.NOT_STARTED, getWebhook.getStatus());
// Disabled webhook state also records last successful time when event was sent
getWebhook = getEntity(webhook.getId(), adminAuthHeaders());
getWebhook = getEntity(webhook.getId(), ADMIN_AUTH_HEADERS);
assertEquals(Status.NOT_STARTED, getWebhook.getStatus());
assertEquals(details.getFirstEventTime(), getWebhook.getFailureDetails().getLastSuccessfulAt());
@ -139,21 +138,21 @@ public class WebhookResourceTest extends EntityResourceTest<Webhook> {
assertEquals(1, details.getEvents().size()); // Event counter remains the same
}
deleteEntity(webhook.getId(), adminAuthHeaders());
deleteEntity(webhook.getId(), ADMIN_AUTH_HEADERS);
}
@Test
void put_updateEndpointURL(TestInfo test) throws URISyntaxException, IOException, InterruptedException {
void put_updateEndpointURL(TestInfo test) throws IOException, InterruptedException {
CreateWebhook create =
createRequest("counter", "", "", null).withEnabled(true).withEndpoint(URI.create("http://invalidUnknowHost"));
Webhook webhook = createAndCheckEntity(create, adminAuthHeaders());
Webhook webhook = createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
// Wait for webhook to be marked as failed
int iteration = 0;
Webhook getWebhook = getEntity(webhook.getId(), adminAuthHeaders());
Webhook getWebhook = getEntity(webhook.getId(), ADMIN_AUTH_HEADERS);
LOG.info("getWebhook {}", getWebhook);
while (getWebhook.getStatus() != Status.FAILED && iteration < 100) {
getWebhook = getEntity(webhook.getId(), adminAuthHeaders());
getWebhook = getEntity(webhook.getId(), ADMIN_AUTH_HEADERS);
LOG.info("getWebhook {}", getWebhook);
Thread.sleep(100);
iteration++;
@ -174,14 +173,13 @@ public class WebhookResourceTest extends EntityResourceTest<Webhook> {
change
.getFieldsUpdated()
.add(new FieldChange().withName("status").withOldValue(Status.FAILED).withNewValue(Status.STARTED));
webhook = updateAndCheckEntity(create, Response.Status.OK, adminAuthHeaders(), UpdateType.MINOR_UPDATE, change);
webhook = updateAndCheckEntity(create, Response.Status.OK, ADMIN_AUTH_HEADERS, UpdateType.MINOR_UPDATE, change);
deleteEntity(webhook.getId(), adminAuthHeaders());
deleteEntity(webhook.getId(), ADMIN_AUTH_HEADERS);
}
@Override
public CreateWebhook createRequest(String name, String description, String displayName, EntityReference owner)
throws URISyntaxException {
public CreateWebhook createRequest(String name, String description, String displayName, EntityReference owner) {
String uri = "http://localhost:" + APP.getLocalPort() + "/api/v1/test/webhook/ignore";
return new CreateWebhook()
.withName(name)
@ -194,14 +192,8 @@ public class WebhookResourceTest extends EntityResourceTest<Webhook> {
}
@Override
public EntityReference getContainer(Object createRequest) throws URISyntaxException {
return null; // No container entity
}
@Override
public void validateCreatedEntity(Webhook webhook, Object request, Map<String, String> authHeaders)
public void validateCreatedEntity(Webhook webhook, CreateWebhook createRequest, Map<String, String> authHeaders)
throws HttpResponseException {
CreateWebhook createRequest = (CreateWebhook) request;
validateCommonEntityFields(
getEntityInterface(webhook), createRequest.getDescription(), TestUtils.getPrincipal(authHeaders), null);
assertEquals(createRequest.getName(), webhook.getName());
@ -211,7 +203,7 @@ public class WebhookResourceTest extends EntityResourceTest<Webhook> {
}
@Override
public void validateUpdatedEntity(Webhook webhook, Object request, Map<String, String> authHeaders)
public void validateUpdatedEntity(Webhook webhook, CreateWebhook request, Map<String, String> authHeaders)
throws HttpResponseException {
validateCreatedEntity(webhook, request, authHeaders);
}
@ -237,14 +229,14 @@ public class WebhookResourceTest extends EntityResourceTest<Webhook> {
* Before a test for every entity resource, create a webhook subscription. At the end of the test, ensure all events
* are delivered over web subscription comparing it with number of events stored in the system.
*/
public void startWebhookSubscription() throws IOException, URISyntaxException {
public void startWebhookSubscription() throws IOException {
// Valid webhook callback
String baseUri = "http://localhost:" + APP.getLocalPort() + "/api/v1/test/webhook/healthy";
createWebhook("healthy", baseUri);
}
/** Start webhook subscription for given entity and various event types */
public void startWebhookEntitySubscriptions(String entity) throws IOException, URISyntaxException {
public void startWebhookEntitySubscriptions(String entity) throws IOException {
String baseUri = "http://localhost:" + APP.getLocalPort() + "/api/v1/test/webhook/filterBased";
// Create webhook with endpoint api/v1/test/webhook/entityCreated/<entity> to receive entityCreated events
@ -275,7 +267,7 @@ public class WebhookResourceTest extends EntityResourceTest<Webhook> {
assertNotNull(callbackEvents);
assertNotNull(callbackEvents.peek());
List<ChangeEvent> actualEvents =
getChangeEvents("*", "*", "*", callbackEvents.peek().getTimestamp(), adminAuthHeaders()).getData();
getChangeEvents("*", "*", "*", callbackEvents.peek().getTimestamp(), ADMIN_AUTH_HEADERS).getData();
waitAndCheckForEvents(actualEvents, callbackEvents, 15, 250);
assertWebhookStatusSuccess("healthy");
}
@ -287,21 +279,21 @@ public class WebhookResourceTest extends EntityResourceTest<Webhook> {
List<ChangeEvent> callbackEvents =
webhookCallbackResource.getEntityCallbackEvents(EventType.ENTITY_CREATED, entity);
long timestamp = callbackEvents.get(0).getTimestamp();
List<ChangeEvent> events = getChangeEvents(entity, null, null, timestamp, adminAuthHeaders()).getData();
List<ChangeEvent> events = getChangeEvents(entity, null, null, timestamp, ADMIN_AUTH_HEADERS).getData();
waitAndCheckForEvents(callbackEvents, events, 30, 100);
// For the entity all the webhooks registered for updated events have the right number of events
callbackEvents = webhookCallbackResource.getEntityCallbackEvents(EventType.ENTITY_UPDATED, entity);
// Use previous date if no update events
timestamp = callbackEvents.size() > 0 ? callbackEvents.get(0).getTimestamp() : timestamp;
events = getChangeEvents(null, entity, null, timestamp, adminAuthHeaders()).getData();
events = getChangeEvents(null, entity, null, timestamp, ADMIN_AUTH_HEADERS).getData();
waitAndCheckForEvents(callbackEvents, events, 30, 100);
// TODO add delete event support
}
@Test
void testDifferentTypesOfWebhooks() throws IOException, InterruptedException, URISyntaxException {
void testDifferentTypesOfWebhooks() throws IOException, InterruptedException {
String baseUri = "http://localhost:" + APP.getLocalPort() + "/api/v1/test/webhook";
// Create multiple webhooks each with different type of response to callback
@ -320,7 +312,7 @@ public class WebhookResourceTest extends EntityResourceTest<Webhook> {
assertNotNull(callbackEvents.peek());
List<ChangeEvent> actualEvents =
getChangeEvents("*", "*", "*", callbackEvents.peek().getTimestamp(), adminAuthHeaders()).getData();
getChangeEvents("*", "*", "*", callbackEvents.peek().getTimestamp(), ADMIN_AUTH_HEADERS).getData();
waitAndCheckForEvents(actualEvents, callbackEvents, 30, 100);
// Check all webhook status
@ -331,34 +323,33 @@ public class WebhookResourceTest extends EntityResourceTest<Webhook> {
assertWebhookStatus("invalidEndpoint", Status.FAILED, null, "UnknownHostException");
// Delete all webhooks
deleteEntity(w1.getId(), adminAuthHeaders());
deleteEntity(w2.getId(), adminAuthHeaders());
deleteEntity(w3.getId(), adminAuthHeaders());
deleteEntity(w4.getId(), adminAuthHeaders());
deleteEntity(w5.getId(), adminAuthHeaders());
deleteEntity(w6.getId(), adminAuthHeaders());
deleteEntity(w1.getId(), ADMIN_AUTH_HEADERS);
deleteEntity(w2.getId(), ADMIN_AUTH_HEADERS);
deleteEntity(w3.getId(), ADMIN_AUTH_HEADERS);
deleteEntity(w4.getId(), ADMIN_AUTH_HEADERS);
deleteEntity(w5.getId(), ADMIN_AUTH_HEADERS);
deleteEntity(w6.getId(), ADMIN_AUTH_HEADERS);
}
public Webhook createWebhook(String name, String uri) throws URISyntaxException, IOException {
public Webhook createWebhook(String name, String uri) throws IOException {
return createWebhook(name, uri, ALL_EVENTS_FILTER);
}
public Webhook createWebhook(String name, String uri, List<EventFilter> filters)
throws URISyntaxException, IOException {
public Webhook createWebhook(String name, String uri, List<EventFilter> filters) throws IOException {
CreateWebhook createWebhook =
createRequest(name, "", "", null).withEndpoint(URI.create(uri)).withEventFilters(filters).withEnabled(true);
return createAndCheckEntity(createWebhook, adminAuthHeaders());
return createAndCheckEntity(createWebhook, ADMIN_AUTH_HEADERS);
}
public void assertWebhookStatusSuccess(String name) throws HttpResponseException {
Webhook webhook = getEntityByName(name, null, "", adminAuthHeaders());
Webhook webhook = getEntityByName(name, "", ADMIN_AUTH_HEADERS);
assertEquals(Status.STARTED, webhook.getStatus());
assertNull(webhook.getFailureDetails());
}
public void assertWebhookStatus(String name, Status status, Integer statusCode, String failedReason)
throws HttpResponseException {
Webhook webhook = getEntityByName(name, null, "", adminAuthHeaders());
Webhook webhook = getEntityByName(name, "", ADMIN_AUTH_HEADERS);
assertEquals(status, webhook.getStatus());
assertEquals(statusCode, webhook.getFailureDetails().getLastFailedStatusCode());
assertEquals(failedReason, webhook.getFailureDetails().getLastFailedReason());

View File

@ -20,7 +20,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.openmetadata.catalog.exception.CatalogExceptionMessage.entityNotFound;
import static org.openmetadata.catalog.security.SecurityUtil.authHeaders;
import static org.openmetadata.catalog.util.TestUtils.adminAuthHeaders;
import static org.openmetadata.catalog.util.TestUtils.ADMIN_AUTH_HEADERS;
import java.io.IOException;
import java.net.URISyntaxException;
@ -67,8 +67,8 @@ public class FeedResourceTest extends CatalogApplicationTest {
public static void setup(TestInfo test) throws IOException, URISyntaxException {
TableResourceTest tableResourceTest = new TableResourceTest();
tableResourceTest.setup(test); // Initialize TableResourceTest for using helper methods
CreateTable createTable = tableResourceTest.create(test);
TABLE = tableResourceTest.createAndCheckEntity(createTable, adminAuthHeaders());
CreateTable createTable = tableResourceTest.createRequest(test);
TABLE = tableResourceTest.createAndCheckEntity(createTable, ADMIN_AUTH_HEADERS);
COLUMNS = Collections.singletonList(new Column().withName("column1").withDataType(ColumnDataType.BIGINT));
TABLE_LINK = String.format("<#E/table/%s>", TABLE.getFullyQualifiedName());
@ -79,7 +79,7 @@ public class FeedResourceTest extends CatalogApplicationTest {
TEAM_LINK = String.format("<#E/team/%s>", TEAM.getName());
CreateThread createThread = create();
THREAD = createAndCheck(createThread, adminAuthHeaders());
THREAD = createAndCheck(createThread, ADMIN_AUTH_HEADERS);
}
@Test
@ -151,10 +151,10 @@ public class FeedResourceTest extends CatalogApplicationTest {
@Test
void post_validThreadAndList_200(TestInfo test) throws HttpResponseException {
int totalThreadCount = listThreads(null, adminAuthHeaders()).getData().size();
int userThreadCount = listThreads(USER_LINK, adminAuthHeaders()).getData().size();
int teamThreadCount = listThreads(TEAM_LINK, adminAuthHeaders()).getData().size();
int tableThreadCount = listThreads(TABLE_LINK, adminAuthHeaders()).getData().size();
int totalThreadCount = listThreads(null, ADMIN_AUTH_HEADERS).getData().size();
int userThreadCount = listThreads(USER_LINK, ADMIN_AUTH_HEADERS).getData().size();
int teamThreadCount = listThreads(TEAM_LINK, ADMIN_AUTH_HEADERS).getData().size();
int tableThreadCount = listThreads(TABLE_LINK, ADMIN_AUTH_HEADERS).getData().size();
CreateThread create =
create()

View File

@ -19,8 +19,8 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.openmetadata.catalog.security.SecurityUtil.authHeaders;
import static org.openmetadata.catalog.util.TestUtils.ADMIN_AUTH_HEADERS;
import static org.openmetadata.catalog.util.TestUtils.ADMIN_USER_NAME;
import static org.openmetadata.catalog.util.TestUtils.adminAuthHeaders;
import static org.openmetadata.catalog.util.TestUtils.assertResponse;
import java.io.IOException;
@ -71,33 +71,36 @@ public class LineageResourceTest extends CatalogApplicationTest {
TableResourceTest tableResourceTest = new TableResourceTest();
tableResourceTest.setup(test); // Initialize TableResourceTest for using helper methods
for (int i = 0; i < TABLE_COUNT; i++) {
CreateTable createTable = tableResourceTest.create(test, i);
TABLES.add(tableResourceTest.createEntity(createTable, adminAuthHeaders()));
CreateTable createTable = tableResourceTest.createRequest(test, i);
TABLES.add(tableResourceTest.createEntity(createTable, ADMIN_AUTH_HEADERS));
}
}
@Test
void put_delete_lineage_withAuthorizer(TestInfo test) throws HttpResponseException {
// Random user cannot update lineage.
User RANDOM_USER =
UserResourceTest.createUser(
UserResourceTest.create(test.getDisplayName() + "_lineage_user"), adminAuthHeaders());
UserResourceTest userResourceTest = new UserResourceTest();
User randomUser =
userResourceTest.createEntity(
userResourceTest.createRequest(test.getDisplayName() + "_lineage_user", "", "", null), ADMIN_AUTH_HEADERS);
// User with Data Steward role. Data Steward role has a default policy to allow update for lineage.
RoleResourceTest roleResourceTest = new RoleResourceTest();
Role dataStewardRole =
RoleResourceTest.getRoleByName(DATA_STEWARD_ROLE_NAME, RoleResource.FIELDS, adminAuthHeaders());
roleResourceTest.getEntityByName(DATA_STEWARD_ROLE_NAME, RoleResource.FIELDS, ADMIN_AUTH_HEADERS);
User userWithDataStewardRole =
UserResourceTest.createUser(
UserResourceTest.create(test.getDisplayName() + "_lineage_user_data_steward")
userResourceTest.createEntity(
userResourceTest
.createRequest(test.getDisplayName() + "_lineage_user_data_steward", "", "", null)
.withRoles(List.of(dataStewardRole.getId())),
adminAuthHeaders());
ADMIN_AUTH_HEADERS);
// Admins are able to add or delete edges.
checkAuthorization(ADMIN_USER_NAME, false);
// User with Data Steward role is able to add or delete edges.
checkAuthorization(userWithDataStewardRole.getName(), false);
// Random user is not able to add or delete edges.
checkAuthorization(RANDOM_USER.getName(), true);
checkAuthorization(randomUser.getName(), true);
}
private void checkAuthorization(String userName, boolean shouldThrowException) throws HttpResponseException {
@ -163,21 +166,21 @@ public class LineageResourceTest extends CatalogApplicationTest {
};
// GET lineage by id
EntityLineage lineage = getLineage(Entity.TABLE, TABLES.get(4).getId(), 3, 3, adminAuthHeaders());
EntityLineage lineage = getLineage(Entity.TABLE, TABLES.get(4).getId(), 3, 3, ADMIN_AUTH_HEADERS);
assertEdges(lineage, expectedUpstreamEdges, expectedDownstreamEdges);
// GET lineage by fqn
lineage = getLineageByName(Entity.TABLE, TABLES.get(4).getFullyQualifiedName(), 3, 3, adminAuthHeaders());
lineage = getLineageByName(Entity.TABLE, TABLES.get(4).getFullyQualifiedName(), 3, 3, ADMIN_AUTH_HEADERS);
assertEdges(lineage, expectedUpstreamEdges, expectedDownstreamEdges);
// Test table4 partial lineage with various upstream and downstream depths
lineage = getLineage(Entity.TABLE, TABLES.get(4).getId(), 0, 0, adminAuthHeaders());
lineage = getLineage(Entity.TABLE, TABLES.get(4).getId(), 0, 0, ADMIN_AUTH_HEADERS);
assertEdges(
lineage, Arrays.copyOfRange(expectedUpstreamEdges, 0, 0), Arrays.copyOfRange(expectedDownstreamEdges, 0, 0));
lineage = getLineage(Entity.TABLE, TABLES.get(4).getId(), 1, 1, adminAuthHeaders());
lineage = getLineage(Entity.TABLE, TABLES.get(4).getId(), 1, 1, ADMIN_AUTH_HEADERS);
assertEdges(
lineage, Arrays.copyOfRange(expectedUpstreamEdges, 0, 3), Arrays.copyOfRange(expectedDownstreamEdges, 0, 3));
lineage = getLineage(Entity.TABLE, TABLES.get(4).getId(), 2, 2, adminAuthHeaders());
lineage = getLineage(Entity.TABLE, TABLES.get(4).getId(), 2, 2, ADMIN_AUTH_HEADERS);
assertEdges(
lineage, Arrays.copyOfRange(expectedUpstreamEdges, 0, 4), Arrays.copyOfRange(expectedDownstreamEdges, 0, 4));
@ -195,7 +198,7 @@ public class LineageResourceTest extends CatalogApplicationTest {
deleteEdge(TABLES.get(4), TABLES.get(8));
deleteEdge(TABLES.get(5), TABLES.get(6));
deleteEdge(TABLES.get(6), TABLES.get(7));
lineage = getLineage(Entity.TABLE, TABLES.get(4).getId(), 2, 2, adminAuthHeaders());
lineage = getLineage(Entity.TABLE, TABLES.get(4).getId(), 2, 2, ADMIN_AUTH_HEADERS);
assertTrue(lineage.getUpstreamEdges().isEmpty());
assertTrue(lineage.getDownstreamEdges().isEmpty());
}
@ -209,7 +212,7 @@ public class LineageResourceTest extends CatalogApplicationTest {
}
public void addEdge(Table from, Table to) throws HttpResponseException {
addEdge(from, to, adminAuthHeaders());
addEdge(from, to, ADMIN_AUTH_HEADERS);
}
private void addEdge(Table from, Table to, Map<String, String> authHeaders) throws HttpResponseException {
@ -222,7 +225,7 @@ public class LineageResourceTest extends CatalogApplicationTest {
}
public void deleteEdge(Table from, Table to) throws HttpResponseException {
deleteEdge(from, to, adminAuthHeaders());
deleteEdge(from, to, ADMIN_AUTH_HEADERS);
}
private void deleteEdge(Table from, Table to, Map<String, String> authHeaders) throws HttpResponseException {

View File

@ -18,8 +18,8 @@ import static javax.ws.rs.core.Response.Status.FORBIDDEN;
import static javax.ws.rs.core.Response.Status.OK;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.openmetadata.catalog.security.SecurityUtil.authHeaders;
import static org.openmetadata.catalog.util.TestUtils.adminAuthHeaders;
import static org.openmetadata.catalog.util.TestUtils.ADMIN_AUTH_HEADERS;
import static org.openmetadata.catalog.util.TestUtils.TEST_AUTH_HEADERS;
import static org.openmetadata.catalog.util.TestUtils.assertListNotNull;
import static org.openmetadata.catalog.util.TestUtils.assertResponse;
@ -50,7 +50,7 @@ import org.openmetadata.catalog.util.ResultList;
import org.openmetadata.catalog.util.TestUtils;
@Slf4j
public class LocationResourceTest extends EntityResourceTest<Location> {
public class LocationResourceTest extends EntityResourceTest<Location, CreateLocation> {
public LocationResourceTest() {
super(
Entity.LOCATION,
@ -70,20 +70,22 @@ public class LocationResourceTest extends EntityResourceTest<Location> {
}
@Override
public Object createRequest(String name, String description, String displayName, EntityReference owner) {
return create(name).withDescription(description).withOwner(owner);
public CreateLocation createRequest(String name, String description, String displayName, EntityReference owner) {
return new CreateLocation()
.withName(name)
.withService(AWS_STORAGE_SERVICE_REFERENCE)
.withDescription(description)
.withOwner(owner);
}
@Override
public EntityReference getContainer(Object createRequest) throws URISyntaxException {
CreateLocation createLocation = (CreateLocation) createRequest;
return createLocation.getService();
public EntityReference getContainer(CreateLocation createRequest) {
return createRequest.getService();
}
@Override
public void validateCreatedEntity(Location location, Object request, Map<String, String> authHeaders)
public void validateCreatedEntity(Location location, CreateLocation createRequest, Map<String, String> authHeaders)
throws HttpResponseException {
CreateLocation createRequest = (CreateLocation) request;
validateCommonEntityFields(
getEntityInterface(location),
createRequest.getDescription(),
@ -101,7 +103,7 @@ public class LocationResourceTest extends EntityResourceTest<Location> {
}
@Override
public void validateUpdatedEntity(Location location, Object request, Map<String, String> authHeaders)
public void validateUpdatedEntity(Location location, CreateLocation request, Map<String, String> authHeaders)
throws HttpResponseException {
validateCreatedEntity(location, request, authHeaders);
}
@ -146,7 +148,7 @@ public class LocationResourceTest extends EntityResourceTest<Location> {
try {
CreateLocation create =
new CreateLocation().withName(subtotal + element).withService(AWS_STORAGE_SERVICE_REFERENCE);
createLocation(create, adminAuthHeaders());
createEntity(create, ADMIN_AUTH_HEADERS);
} catch (HttpResponseException e) {
throw new RuntimeException(e);
}
@ -161,35 +163,35 @@ public class LocationResourceTest extends EntityResourceTest<Location> {
1000000,
null,
null,
adminAuthHeaders());
ADMIN_AUTH_HEADERS);
assertEquals(5, allLocations.getData().size(), "Wrong number of prefix locations");
}
@Test
void post_validLocations_as_admin_200_OK(TestInfo test) throws IOException {
// Create team with different optional fields
CreateLocation create = create(test);
createAndCheckEntity(create, adminAuthHeaders());
CreateLocation create = createRequest(test);
createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
create.withName(getLocationName(test, 1)).withDescription("description");
createAndCheckEntity(create, adminAuthHeaders());
create.withName(getEntityName(test, 1)).withDescription("description");
createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
}
@Test
void post_locationWithUserOwner_200_ok(TestInfo test) throws IOException {
createAndCheckEntity(create(test).withOwner(USER_OWNER1), adminAuthHeaders());
createAndCheckEntity(createRequest(test).withOwner(USER_OWNER1), ADMIN_AUTH_HEADERS);
}
@Test
void post_locationWithTeamOwner_200_ok(TestInfo test) throws IOException {
createAndCheckEntity(create(test).withOwner(TEAM_OWNER1), adminAuthHeaders());
createAndCheckEntity(createRequest(test).withOwner(TEAM_OWNER1), ADMIN_AUTH_HEADERS);
}
@Test
void post_location_as_non_admin_401(TestInfo test) {
CreateLocation create = create(test);
CreateLocation create = createRequest(test);
HttpResponseException exception =
assertThrows(HttpResponseException.class, () -> createLocation(create, authHeaders("test@open-metadata.org")));
assertThrows(HttpResponseException.class, () -> createEntity(create, TEST_AUTH_HEADERS));
assertResponse(exception, FORBIDDEN, "Principal: CatalogPrincipal{name='test'} is not admin");
}
@ -197,13 +199,13 @@ public class LocationResourceTest extends EntityResourceTest<Location> {
void post_locationWithoutRequiredFields_4xx(TestInfo test) {
HttpResponseException exception =
assertThrows(
HttpResponseException.class, () -> createLocation(create(test).withName(null), adminAuthHeaders()));
HttpResponseException.class, () -> createEntity(createRequest(test).withName(null), ADMIN_AUTH_HEADERS));
assertResponse(exception, BAD_REQUEST, "[name must not be null]");
// Service is required field
exception =
assertThrows(
HttpResponseException.class, () -> createLocation(create(test).withService(null), adminAuthHeaders()));
HttpResponseException.class, () -> createEntity(createRequest(test).withService(null), ADMIN_AUTH_HEADERS));
assertResponse(exception, BAD_REQUEST, "[service must not be null]");
}
@ -213,7 +215,7 @@ public class LocationResourceTest extends EntityResourceTest<Location> {
// Create location for each service and test APIs
for (EntityReference service : differentServices) {
createAndCheckEntity(create(test).withService(service), adminAuthHeaders());
createAndCheckEntity(createRequest(test).withService(service), ADMIN_AUTH_HEADERS);
// List locations by filtering on service name and ensure right locations are returned
Map<String, String> queryParams =
@ -222,7 +224,7 @@ public class LocationResourceTest extends EntityResourceTest<Location> {
put("service", service.getName());
}
};
ResultList<Location> list = listEntities(queryParams, adminAuthHeaders());
ResultList<Location> list = listEntities(queryParams, ADMIN_AUTH_HEADERS);
for (Location location : list.getData()) {
assertEquals(service.getName(), location.getService().getName());
}
@ -231,11 +233,12 @@ public class LocationResourceTest extends EntityResourceTest<Location> {
@Test
void put_locationNonEmptyDescriptionUpdate_200(TestInfo test) throws IOException {
CreateLocation request = create(test).withService(AWS_STORAGE_SERVICE_REFERENCE).withDescription("description");
createAndCheckEntity(request, adminAuthHeaders());
CreateLocation request =
createRequest(test).withService(AWS_STORAGE_SERVICE_REFERENCE).withDescription("description");
createAndCheckEntity(request, ADMIN_AUTH_HEADERS);
// Updating description is ignored when backend already has description
Location location = updateLocation(request.withDescription("newDescription"), OK, adminAuthHeaders());
Location location = updateLocation(request.withDescription("newDescription"), OK, ADMIN_AUTH_HEADERS);
assertEquals("description", location.getDescription());
}
@ -244,11 +247,6 @@ public class LocationResourceTest extends EntityResourceTest<Location> {
return TestUtils.put(getResource("locations"), create, Location.class, status, authHeaders);
}
public static Location createLocation(CreateLocation create, Map<String, String> authHeaders)
throws HttpResponseException {
return TestUtils.post(getResource("locations"), create, Location.class, authHeaders);
}
/** Validate returned fields GET .../locations/{id}?fields="..." or GET .../locations/name/{fqn}?fields="..." */
@Override
public void validateGetWithDifferentFields(Location location, boolean byName) throws HttpResponseException {
@ -256,8 +254,8 @@ public class LocationResourceTest extends EntityResourceTest<Location> {
String fields = "owner";
location =
byName
? getEntityByName(location.getFullyQualifiedName(), null, fields, adminAuthHeaders())
: getEntity(location.getId(), fields, adminAuthHeaders());
? getEntityByName(location.getFullyQualifiedName(), fields, ADMIN_AUTH_HEADERS)
: getEntity(location.getId(), fields, ADMIN_AUTH_HEADERS);
assertListNotNull(location.getOwner(), location.getService(), location.getServiceType());
// TODO add other fields
}
@ -273,24 +271,4 @@ public class LocationResourceTest extends EntityResourceTest<Location> {
target = after != null ? target.queryParam("after", after) : target;
return TestUtils.get(target, LocationList.class, authHeaders);
}
public static String getLocationName(TestInfo test) {
return String.format("location_%s", test.getDisplayName());
}
public static String getLocationName(TestInfo test, int index) {
return String.format("location%d_%s", index, test.getDisplayName());
}
private CreateLocation create(TestInfo test) {
return new CreateLocation().withName(getEntityName(test)).withService(AWS_STORAGE_SERVICE_REFERENCE);
}
private CreateLocation create(String name) {
return create(name, AWS_STORAGE_SERVICE_REFERENCE);
}
public static CreateLocation create(String name, EntityReference storageServiceReference) {
return new CreateLocation().withName(name).withService(storageServiceReference);
}
}

View File

@ -17,11 +17,11 @@ import static javax.ws.rs.core.Response.Status.FORBIDDEN;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.openmetadata.catalog.security.SecurityUtil.authHeaders;
import static org.openmetadata.catalog.util.TestUtils.ADMIN_AUTH_HEADERS;
import static org.openmetadata.catalog.util.TestUtils.TEST_AUTH_HEADERS;
import static org.openmetadata.catalog.util.TestUtils.UpdateType.MAJOR_UPDATE;
import static org.openmetadata.catalog.util.TestUtils.UpdateType.MINOR_UPDATE;
import static org.openmetadata.catalog.util.TestUtils.UpdateType.NO_CHANGE;
import static org.openmetadata.catalog.util.TestUtils.adminAuthHeaders;
import static org.openmetadata.catalog.util.TestUtils.assertListNotNull;
import static org.openmetadata.catalog.util.TestUtils.assertResponse;
@ -42,29 +42,19 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
import org.junit.jupiter.api.TestMethodOrder;
import org.openmetadata.catalog.Entity;
import org.openmetadata.catalog.api.data.CreateDatabase;
import org.openmetadata.catalog.api.data.CreateMlModel;
import org.openmetadata.catalog.api.data.CreateTable;
import org.openmetadata.catalog.api.services.CreateDashboardService;
import org.openmetadata.catalog.api.services.CreateDashboardService.DashboardServiceType;
import org.openmetadata.catalog.entity.data.Dashboard;
import org.openmetadata.catalog.entity.data.Database;
import org.openmetadata.catalog.entity.data.MlModel;
import org.openmetadata.catalog.entity.data.Table;
import org.openmetadata.catalog.entity.services.DashboardService;
import org.openmetadata.catalog.jdbi3.DashboardRepository.DashboardEntityInterface;
import org.openmetadata.catalog.jdbi3.DashboardServiceRepository.DashboardServiceEntityInterface;
import org.openmetadata.catalog.jdbi3.MlModelRepository;
import org.openmetadata.catalog.jdbi3.TableRepository.TableEntityInterface;
import org.openmetadata.catalog.resources.EntityResourceTest;
import org.openmetadata.catalog.resources.dashboards.DashboardResourceTest;
import org.openmetadata.catalog.resources.databases.DatabaseResourceTest;
import org.openmetadata.catalog.resources.databases.TableResourceTest;
import org.openmetadata.catalog.resources.mlmodels.MlModelResource.MlModelList;
import org.openmetadata.catalog.resources.services.DashboardServiceResourceTest;
import org.openmetadata.catalog.type.ChangeDescription;
import org.openmetadata.catalog.type.Column;
import org.openmetadata.catalog.type.ColumnDataType;
import org.openmetadata.catalog.type.EntityReference;
import org.openmetadata.catalog.type.FeatureSourceDataType;
import org.openmetadata.catalog.type.FieldChange;
@ -79,14 +69,11 @@ import org.openmetadata.catalog.util.TestUtils;
@Slf4j
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class MlModelResourceTest extends EntityResourceTest<MlModel> {
public class MlModelResourceTest extends EntityResourceTest<MlModel, CreateMlModel> {
public static EntityReference SUPERSET_REFERENCE;
public static final String ALGORITHM = "regression";
public static Dashboard DASHBOARD;
public static EntityReference DASHBOARD_REFERENCE;
public static Database DATABASE;
public static List<Column> COLUMNS;
public static Table TABLE;
public static EntityReference TABLE_REFERENCE;
@ -125,88 +112,68 @@ public class MlModelResourceTest extends EntityResourceTest<MlModel> {
public void setup(TestInfo test) throws IOException, URISyntaxException {
super.setup(test);
CreateDashboardService createService =
new CreateDashboardService()
.withName("superset")
.withServiceType(DashboardServiceType.Superset)
.withDashboardUrl(TestUtils.DASHBOARD_URL);
DashboardService service = new DashboardServiceResourceTest().createEntity(createService, adminAuthHeaders());
SUPERSET_REFERENCE = new DashboardServiceEntityInterface(service).getEntityReference();
DashboardResourceTest dashboardResourceTest = new DashboardResourceTest();
DASHBOARD =
dashboardResourceTest.createDashboard(
dashboardResourceTest.create(test).withService(SUPERSET_REFERENCE), adminAuthHeaders());
dashboardResourceTest.createEntity(
dashboardResourceTest.createRequest(test).withCharts(null), ADMIN_AUTH_HEADERS);
DASHBOARD_REFERENCE = new DashboardEntityInterface(DASHBOARD).getEntityReference();
DatabaseResourceTest databaseResourceTest = new DatabaseResourceTest();
CreateDatabase create = databaseResourceTest.create(test).withService(SNOWFLAKE_REFERENCE);
DATABASE = databaseResourceTest.createAndCheckEntity(create, adminAuthHeaders());
COLUMNS = Collections.singletonList(new Column().withName("age").withDataType(ColumnDataType.INT));
CreateTable createTable = new CreateTable().withName("myTable").withDatabase(DATABASE.getId()).withColumns(COLUMNS);
TableResourceTest tableResourceTest = new TableResourceTest();
TABLE = tableResourceTest.createAndCheckEntity(createTable, adminAuthHeaders());
TABLE = tableResourceTest.createAndCheckEntity(createTable, ADMIN_AUTH_HEADERS);
TABLE_REFERENCE = new TableEntityInterface(TABLE).getEntityReference();
}
public static MlModel createMlModel(CreateMlModel create, Map<String, String> authHeaders)
throws HttpResponseException {
return new MlModelResourceTest().createEntity(create, authHeaders);
}
@Test
void post_validMlModels_as_admin_200_OK(TestInfo test) throws IOException {
// Create valid model
CreateMlModel create = create(test);
createAndCheckEntity(create, adminAuthHeaders());
CreateMlModel create = createRequest(test);
createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
create.withName(getEntityName(test, 1)).withDescription("description");
createAndCheckEntity(create, adminAuthHeaders());
createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
}
@Test
void post_MlModelWithUserOwner_200_ok(TestInfo test) throws IOException {
createAndCheckEntity(create(test).withOwner(USER_OWNER1), adminAuthHeaders());
createAndCheckEntity(createRequest(test).withOwner(USER_OWNER1), ADMIN_AUTH_HEADERS);
}
@Test
void post_MlModelWithTeamOwner_200_ok(TestInfo test) throws IOException {
createAndCheckEntity(create(test).withOwner(TEAM_OWNER1).withDisplayName("Model1"), adminAuthHeaders());
createAndCheckEntity(createRequest(test).withOwner(TEAM_OWNER1).withDisplayName("Model1"), ADMIN_AUTH_HEADERS);
}
@Test
void post_MlModelWithoutFeatures_200_ok(TestInfo test) throws IOException {
CreateMlModel create = new CreateMlModel().withName(getEntityName(test, 0)).withAlgorithm(ALGORITHM);
createAndCheckEntity(create, adminAuthHeaders());
CreateMlModel create = createRequest(test).withAlgorithm(ALGORITHM);
createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
}
@Test
void post_MlModelWithDashboard_200_ok(TestInfo test) throws IOException {
CreateMlModel create = create(test).withDashboard(DASHBOARD_REFERENCE);
createAndCheckEntity(create, adminAuthHeaders());
CreateMlModel create = createRequest(test).withDashboard(DASHBOARD_REFERENCE);
createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
}
@Test
void post_MlModelWitMlStore_200_ok(TestInfo test) throws IOException {
CreateMlModel create = create(test).withMlStore(ML_STORE);
createAndCheckEntity(create, adminAuthHeaders());
CreateMlModel create = createRequest(test).withMlStore(ML_STORE);
createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
}
@Test
void post_MlModelWitServer_200_ok(TestInfo test) throws IOException {
CreateMlModel create = create(test).withServer(SERVER);
createAndCheckEntity(create, adminAuthHeaders());
CreateMlModel create = createRequest(test).withServer(SERVER);
createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
}
@Test
void post_MlModel_as_non_admin_401(TestInfo test) {
CreateMlModel create = create(test);
CreateMlModel create = createRequest(test);
assertResponse(
() -> createMlModel(create, authHeaders("test@open-metadata.org")),
() -> createEntity(create, TEST_AUTH_HEADERS),
FORBIDDEN,
"Principal: CatalogPrincipal{name='test'} is not admin");
}
@ -214,95 +181,95 @@ public class MlModelResourceTest extends EntityResourceTest<MlModel> {
@Test
void put_MlModelUpdateWithNoChange_200(TestInfo test) throws IOException {
// Create a Model with POST
CreateMlModel request = create(test).withOwner(USER_OWNER1);
MlModel model = createAndCheckEntity(request, adminAuthHeaders());
CreateMlModel request = createRequest(test).withOwner(USER_OWNER1);
MlModel model = createAndCheckEntity(request, ADMIN_AUTH_HEADERS);
ChangeDescription change = getChangeDescription(model.getVersion());
// Update Model two times successfully with PUT requests
updateAndCheckEntity(request, Status.OK, adminAuthHeaders(), NO_CHANGE, change);
updateAndCheckEntity(request, Status.OK, ADMIN_AUTH_HEADERS, NO_CHANGE, change);
}
@Test
void put_MlModelUpdateAlgorithm_200(TestInfo test) throws IOException {
CreateMlModel request = create(test);
MlModel model = createAndCheckEntity(request, adminAuthHeaders());
CreateMlModel request = createRequest(test);
MlModel model = createAndCheckEntity(request, ADMIN_AUTH_HEADERS);
ChangeDescription change = getChangeDescription(model.getVersion());
change
.getFieldsUpdated()
.add(new FieldChange().withName("algorithm").withNewValue("SVM").withOldValue("regression"));
updateAndCheckEntity(request.withAlgorithm("SVM"), Status.OK, adminAuthHeaders(), MAJOR_UPDATE, change);
updateAndCheckEntity(request.withAlgorithm("SVM"), Status.OK, ADMIN_AUTH_HEADERS, MAJOR_UPDATE, change);
}
@Test
void put_MlModelAddDashboard_200(TestInfo test) throws IOException {
CreateMlModel request = create(test);
MlModel model = createAndCheckEntity(request, adminAuthHeaders());
CreateMlModel request = createRequest(test).withDashboard(null);
MlModel model = createAndCheckEntity(request, ADMIN_AUTH_HEADERS);
ChangeDescription change = getChangeDescription(model.getVersion());
change.getFieldsAdded().add(new FieldChange().withName("dashboard").withNewValue(DASHBOARD_REFERENCE));
updateAndCheckEntity(
request.withDashboard(DASHBOARD_REFERENCE), Status.OK, adminAuthHeaders(), MINOR_UPDATE, change);
request.withDashboard(DASHBOARD_REFERENCE), Status.OK, ADMIN_AUTH_HEADERS, MINOR_UPDATE, change);
}
@Test
void put_MlModelAddInvalidDashboard_200(TestInfo test) {
CreateMlModel request = create(test);
CreateMlModel request = createRequest(test);
// Create a made up dashboard reference by picking up a random UUID
EntityReference dashboard = new EntityReference().withId(USER1.getId()).withType("dashboard");
assertResponse(
() -> createMlModel(request.withDashboard(dashboard), adminAuthHeaders()),
() -> createEntity(request.withDashboard(dashboard), ADMIN_AUTH_HEADERS),
Status.NOT_FOUND,
String.format("dashboard instance for %s not found", USER1.getId()));
}
@Test
void put_MlModelAddServer_200(TestInfo test) throws IOException {
CreateMlModel request = create(test);
MlModel model = createAndCheckEntity(request, adminAuthHeaders());
CreateMlModel request = createRequest(test);
MlModel model = createAndCheckEntity(request, ADMIN_AUTH_HEADERS);
ChangeDescription change = getChangeDescription(model.getVersion());
change.getFieldsAdded().add(new FieldChange().withName("server").withNewValue(SERVER));
updateAndCheckEntity(request.withServer(SERVER), Status.OK, adminAuthHeaders(), MAJOR_UPDATE, change);
updateAndCheckEntity(request.withServer(SERVER), Status.OK, ADMIN_AUTH_HEADERS, MAJOR_UPDATE, change);
}
@Test
void put_MlModelUpdateServer_200(TestInfo test) throws IOException {
CreateMlModel request = create(test).withServer(SERVER);
MlModel model = createAndCheckEntity(request, adminAuthHeaders());
CreateMlModel request = createRequest(test).withServer(SERVER);
MlModel model = createAndCheckEntity(request, ADMIN_AUTH_HEADERS);
ChangeDescription change = getChangeDescription(model.getVersion());
URI newServer = URI.create("http://localhost.com/mlModel/v2");
change.getFieldsUpdated().add(new FieldChange().withName("server").withNewValue(newServer).withOldValue(SERVER));
updateAndCheckEntity(request.withServer(newServer), Status.OK, adminAuthHeaders(), MAJOR_UPDATE, change);
updateAndCheckEntity(request.withServer(newServer), Status.OK, ADMIN_AUTH_HEADERS, MAJOR_UPDATE, change);
}
@Test
void put_MlModelAddMlStore_200(TestInfo test) throws IOException {
CreateMlModel request = create(test);
MlModel model = createAndCheckEntity(request, adminAuthHeaders());
CreateMlModel request = createRequest(test);
MlModel model = createAndCheckEntity(request, ADMIN_AUTH_HEADERS);
ChangeDescription change = getChangeDescription(model.getVersion());
change.getFieldsAdded().add(new FieldChange().withName("mlStore").withNewValue(ML_STORE));
updateAndCheckEntity(request.withMlStore(ML_STORE), Status.OK, adminAuthHeaders(), MINOR_UPDATE, change);
updateAndCheckEntity(request.withMlStore(ML_STORE), Status.OK, ADMIN_AUTH_HEADERS, MINOR_UPDATE, change);
}
@Test
void put_MlModelAddMlFeatures_200(TestInfo test) throws IOException {
CreateMlModel request = new CreateMlModel().withName(getEntityName(test)).withAlgorithm(ALGORITHM);
MlModel model = createAndCheckEntity(request, adminAuthHeaders());
MlModel model = createAndCheckEntity(request, ADMIN_AUTH_HEADERS);
ChangeDescription change = getChangeDescription(model.getVersion());
change.getFieldsAdded().add(new FieldChange().withName("mlFeatures").withNewValue(ML_FEATURES));
updateAndCheckEntity(request.withMlFeatures(ML_FEATURES), Status.OK, adminAuthHeaders(), MINOR_UPDATE, change);
updateAndCheckEntity(request.withMlFeatures(ML_FEATURES), Status.OK, ADMIN_AUTH_HEADERS, MINOR_UPDATE, change);
}
@Test
void put_MlModelUpdateMlFeatures_200(TestInfo test) throws IOException {
CreateMlModel request = create(test);
MlModel model = createAndCheckEntity(request, adminAuthHeaders());
CreateMlModel request = createRequest(test);
MlModel model = createAndCheckEntity(request, ADMIN_AUTH_HEADERS);
//
// Add new ML features from previously empty
@ -314,13 +281,13 @@ public class MlModelResourceTest extends EntityResourceTest<MlModel> {
change.getFieldsAdded().add(new FieldChange().withName("mlFeatures").withNewValue(newFeatures));
change.getFieldsDeleted().add(new FieldChange().withName("mlFeatures").withOldValue(ML_FEATURES));
updateAndCheckEntity(request.withMlFeatures(newFeatures), Status.OK, adminAuthHeaders(), MINOR_UPDATE, change);
updateAndCheckEntity(request.withMlFeatures(newFeatures), Status.OK, ADMIN_AUTH_HEADERS, MINOR_UPDATE, change);
}
@Test
void put_MlModelWithDataSource_200(TestInfo test) throws IOException {
CreateMlModel request = create(test);
MlModel model = createAndCheckEntity(request, adminAuthHeaders());
CreateMlModel request = createRequest(test);
MlModel model = createAndCheckEntity(request, ADMIN_AUTH_HEADERS);
MlFeature newMlFeature =
new MlFeature()
@ -338,12 +305,12 @@ public class MlModelResourceTest extends EntityResourceTest<MlModel> {
change.getFieldsAdded().add(new FieldChange().withName("mlFeatures").withNewValue(newFeatures));
change.getFieldsDeleted().add(new FieldChange().withName("mlFeatures").withOldValue(ML_FEATURES));
updateAndCheckEntity(request.withMlFeatures(newFeatures), Status.OK, adminAuthHeaders(), MINOR_UPDATE, change);
updateAndCheckEntity(request.withMlFeatures(newFeatures), Status.OK, ADMIN_AUTH_HEADERS, MINOR_UPDATE, change);
}
@Test
void put_MlModelWithInvalidDataSource_400(TestInfo test) throws IOException {
CreateMlModel request = create(test);
void put_MlModelWithInvalidDataSource_400(TestInfo test) {
CreateMlModel request = createRequest(test);
// Create a made up table reference by picking up a random UUID
EntityReference invalid_table = new EntityReference().withId(USER1.getId()).withType("table");
@ -361,7 +328,7 @@ public class MlModelResourceTest extends EntityResourceTest<MlModel> {
List<MlFeature> newFeatures = Collections.singletonList(newMlFeature);
assertResponse(
() -> createMlModel(request.withMlFeatures(newFeatures), adminAuthHeaders()),
() -> createEntity(request.withMlFeatures(newFeatures), ADMIN_AUTH_HEADERS),
Status.NOT_FOUND,
String.format("table instance for %s not found", USER1.getId()));
}
@ -369,36 +336,36 @@ public class MlModelResourceTest extends EntityResourceTest<MlModel> {
@Test
void put_MlModelAddMlHyperParams_200(TestInfo test) throws IOException {
CreateMlModel request = new CreateMlModel().withName(getEntityName(test)).withAlgorithm(ALGORITHM);
MlModel model = createAndCheckEntity(request, adminAuthHeaders());
MlModel model = createAndCheckEntity(request, ADMIN_AUTH_HEADERS);
ChangeDescription change = getChangeDescription(model.getVersion());
change.getFieldsAdded().add(new FieldChange().withName("mlHyperParameters").withNewValue(ML_HYPERPARAMS));
updateAndCheckEntity(
request.withMlHyperParameters(ML_HYPERPARAMS), Status.OK, adminAuthHeaders(), MINOR_UPDATE, change);
request.withMlHyperParameters(ML_HYPERPARAMS), Status.OK, ADMIN_AUTH_HEADERS, MINOR_UPDATE, change);
}
@Test
void put_MlModelAddTarget_200(TestInfo test) throws IOException {
CreateMlModel request = create(test);
MlModel model = createAndCheckEntity(request, adminAuthHeaders());
CreateMlModel request = createRequest(test);
MlModel model = createAndCheckEntity(request, ADMIN_AUTH_HEADERS);
ChangeDescription change = getChangeDescription(model.getVersion());
change.getFieldsAdded().add(new FieldChange().withName("target").withNewValue("myTarget"));
updateAndCheckEntity(request.withTarget("myTarget"), Status.OK, adminAuthHeaders(), MAJOR_UPDATE, change);
updateAndCheckEntity(request.withTarget("myTarget"), Status.OK, ADMIN_AUTH_HEADERS, MAJOR_UPDATE, change);
}
@Test
void put_MlModelUpdateTarget_200(TestInfo test) throws IOException {
CreateMlModel request = create(test).withTarget("origTarget");
MlModel model = createAndCheckEntity(request, adminAuthHeaders());
CreateMlModel request = createRequest(test).withTarget("origTarget");
MlModel model = createAndCheckEntity(request, ADMIN_AUTH_HEADERS);
ChangeDescription change = getChangeDescription(model.getVersion());
change
.getFieldsUpdated()
.add(new FieldChange().withName("target").withNewValue("newTarget").withOldValue("origTarget"));
updateAndCheckEntity(request.withTarget("newTarget"), Status.OK, adminAuthHeaders(), MAJOR_UPDATE, change);
updateAndCheckEntity(request.withTarget("newTarget"), Status.OK, ADMIN_AUTH_HEADERS, MAJOR_UPDATE, change);
}
/** Validate returned fields GET .../models/{id}?fields="..." or GET .../models/name/{fqn}?fields="..." */
@ -408,8 +375,8 @@ public class MlModelResourceTest extends EntityResourceTest<MlModel> {
String fields = "owner";
model =
byName
? getEntityByName(model.getFullyQualifiedName(), null, fields, adminAuthHeaders())
: getEntity(model.getId(), fields, adminAuthHeaders());
? getEntityByName(model.getFullyQualifiedName(), fields, ADMIN_AUTH_HEADERS)
: getEntity(model.getId(), fields, ADMIN_AUTH_HEADERS);
assertNotNull(model.getOwner(), model.getAlgorithm());
assertNull(model.getDashboard());
@ -417,8 +384,8 @@ public class MlModelResourceTest extends EntityResourceTest<MlModel> {
fields = "mlFeatures,mlHyperParameters";
model =
byName
? getEntityByName(model.getFullyQualifiedName(), null, fields, adminAuthHeaders())
: getEntity(model.getId(), fields, adminAuthHeaders());
? getEntityByName(model.getFullyQualifiedName(), fields, ADMIN_AUTH_HEADERS)
: getEntity(model.getId(), fields, ADMIN_AUTH_HEADERS);
assertListNotNull(model.getAlgorithm(), model.getMlFeatures(), model.getMlHyperParameters());
assertNull(model.getDashboard());
@ -426,8 +393,8 @@ public class MlModelResourceTest extends EntityResourceTest<MlModel> {
fields = "owner,algorithm";
model =
byName
? getEntityByName(model.getFullyQualifiedName(), null, fields, adminAuthHeaders())
: getEntity(model.getId(), fields, adminAuthHeaders());
? getEntityByName(model.getFullyQualifiedName(), fields, ADMIN_AUTH_HEADERS)
: getEntity(model.getId(), fields, ADMIN_AUTH_HEADERS);
assertListNotNull(model.getOwner(), model.getAlgorithm());
assertNull(model.getDashboard());
@ -435,27 +402,19 @@ public class MlModelResourceTest extends EntityResourceTest<MlModel> {
fields = "owner,algorithm,dashboard";
model =
byName
? getEntityByName(model.getFullyQualifiedName(), null, fields, adminAuthHeaders())
: getEntity(model.getId(), fields, adminAuthHeaders());
? getEntityByName(model.getFullyQualifiedName(), fields, ADMIN_AUTH_HEADERS)
: getEntity(model.getId(), fields, ADMIN_AUTH_HEADERS);
assertListNotNull(model.getOwner(), model.getAlgorithm(), model.getDashboard());
TestUtils.validateEntityReference(model.getDashboard());
}
private CreateMlModel create(TestInfo test) {
return create(getEntityName(test));
}
private CreateMlModel create(String name) {
@Override
public CreateMlModel createRequest(String name, String description, String displayName, EntityReference owner) {
return new CreateMlModel()
.withName(name)
.withAlgorithm(ALGORITHM)
.withMlFeatures(ML_FEATURES)
.withMlHyperParameters(ML_HYPERPARAMS);
}
@Override
public Object createRequest(String name, String description, String displayName, EntityReference owner) {
return create(name)
.withMlHyperParameters(ML_HYPERPARAMS)
.withDescription(description)
.withDisplayName(displayName)
.withOwner(owner)
@ -463,12 +422,7 @@ public class MlModelResourceTest extends EntityResourceTest<MlModel> {
}
@Override
public EntityReference getContainer(Object createRequest) throws URISyntaxException {
return null; // No container entity
}
@Override
public void validateUpdatedEntity(MlModel mlModel, Object request, Map<String, String> authHeaders)
public void validateUpdatedEntity(MlModel mlModel, CreateMlModel request, Map<String, String> authHeaders)
throws HttpResponseException {
validateCreatedEntity(mlModel, request, authHeaders);
}
@ -538,9 +492,8 @@ public class MlModelResourceTest extends EntityResourceTest<MlModel> {
}
@Override
public void validateCreatedEntity(MlModel createdEntity, Object request, Map<String, String> authHeaders)
public void validateCreatedEntity(MlModel createdEntity, CreateMlModel createRequest, Map<String, String> authHeaders)
throws HttpResponseException {
CreateMlModel createRequest = (CreateMlModel) request;
validateCommonEntityFields(
getEntityInterface(createdEntity),
createRequest.getDescription(),
@ -566,10 +519,12 @@ public class MlModelResourceTest extends EntityResourceTest<MlModel> {
return;
}
if (fieldName.contains("mlFeatures")) {
@SuppressWarnings("unchecked")
List<MlFeature> expectedFeatures = (List<MlFeature>) expected;
List<MlFeature> actualFeatures = JsonUtils.readObjects(actual.toString(), MlFeature.class);
assertListProperty(expectedFeatures, actualFeatures, assertMlFeature);
} else if (fieldName.contains("mlHyperParameters")) {
@SuppressWarnings("unchecked")
List<MlHyperParameter> expectedConstraints = (List<MlHyperParameter>) expected;
List<MlHyperParameter> actualConstraints = JsonUtils.readObjects(actual.toString(), MlHyperParameter.class);
assertListProperty(expectedConstraints, actualConstraints, assertMlHyperParam);

View File

@ -29,9 +29,9 @@ import static org.openmetadata.catalog.airflow.AirflowUtils.INGESTION_OPTIONS;
import static org.openmetadata.catalog.airflow.AirflowUtils.INGESTION_PASSWORD;
import static org.openmetadata.catalog.airflow.AirflowUtils.INGESTION_SERVICE_NAME;
import static org.openmetadata.catalog.airflow.AirflowUtils.INGESTION_USERNAME;
import static org.openmetadata.catalog.security.SecurityUtil.authHeaders;
import static org.openmetadata.catalog.util.TestUtils.ADMIN_AUTH_HEADERS;
import static org.openmetadata.catalog.util.TestUtils.TEST_AUTH_HEADERS;
import static org.openmetadata.catalog.util.TestUtils.UpdateType.MINOR_UPDATE;
import static org.openmetadata.catalog.util.TestUtils.adminAuthHeaders;
import static org.openmetadata.catalog.util.TestUtils.assertListNotNull;
import static org.openmetadata.catalog.util.TestUtils.assertResponse;
@ -83,7 +83,7 @@ import org.openmetadata.catalog.util.JsonUtils;
import org.openmetadata.catalog.util.TestUtils;
@Slf4j
public class AirflowPipelineResourceTest extends EntityOperationsResourceTest<AirflowPipeline> {
public class AirflowPipelineResourceTest extends EntityOperationsResourceTest<AirflowPipeline, CreateAirflowPipeline> {
public static PipelineConfig INGESTION_CONFIG;
public static AirflowConfiguration AIRFLOW_CONFIG;
public static DatabaseServiceResourceTest DATABASE_SERVICE_RESOURCE_TEST;
@ -123,20 +123,28 @@ public class AirflowPipelineResourceTest extends EntityOperationsResourceTest<Ai
}
@Override
public Object createRequest(String name, String description, String displayName, EntityReference owner) {
return create(name).withDescription(description).withDisplayName(displayName).withOwner(owner);
public CreateAirflowPipeline createRequest(
String name, String description, String displayName, EntityReference owner) {
return new CreateAirflowPipeline()
.withName(name)
.withPipelineType(PipelineType.METADATA)
.withService(BIGQUERY_REFERENCE)
.withPipelineConfig(INGESTION_CONFIG)
.withStartDate("2021-11-21")
.withDescription(description)
.withDisplayName(displayName)
.withOwner(owner);
}
@Override
public EntityReference getContainer(Object createRequest) throws URISyntaxException {
CreateAirflowPipeline createIngestion = (CreateAirflowPipeline) createRequest;
return createIngestion.getService();
public EntityReference getContainer(CreateAirflowPipeline createRequest) {
return createRequest.getService();
}
@Override
public void validateCreatedEntity(AirflowPipeline ingestion, Object request, Map<String, String> authHeaders)
public void validateCreatedEntity(
AirflowPipeline ingestion, CreateAirflowPipeline createRequest, Map<String, String> authHeaders)
throws HttpResponseException {
CreateAirflowPipeline createRequest = (CreateAirflowPipeline) request;
validateCommonEntityFields(
getEntityInterface(ingestion),
createRequest.getDescription(),
@ -148,7 +156,8 @@ public class AirflowPipelineResourceTest extends EntityOperationsResourceTest<Ai
}
@Override
public void validateUpdatedEntity(AirflowPipeline ingestion, Object request, Map<String, String> authHeaders)
public void validateUpdatedEntity(
AirflowPipeline ingestion, CreateAirflowPipeline request, Map<String, String> authHeaders)
throws HttpResponseException {
validateCreatedEntity(ingestion, request, authHeaders);
}
@ -182,49 +191,49 @@ public class AirflowPipelineResourceTest extends EntityOperationsResourceTest<Ai
@Test
void post_validAirflowPipeline_as_admin_200_OK(TestInfo test) throws IOException {
// Create team with different optional fields
CreateAirflowPipeline create = create(test);
createAndCheckEntity(create, adminAuthHeaders());
CreateAirflowPipeline create = createRequest(test);
createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
create.withName(getEntityName(test, 1)).withDescription("description");
createAndCheckEntity(create, adminAuthHeaders());
createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
}
@Test
void post_AirflowPipelineWithUserOwner_200_ok(TestInfo test) throws IOException {
createAndCheckEntity(create(test).withOwner(USER_OWNER1), adminAuthHeaders());
createAndCheckEntity(createRequest(test).withOwner(USER_OWNER1), ADMIN_AUTH_HEADERS);
}
@Test
void post_AirflowPipelineWithTeamOwner_200_ok(TestInfo test) throws IOException {
createAndCheckEntity(create(test).withOwner(TEAM_OWNER1).withDisplayName("Ingestion1"), adminAuthHeaders());
createAndCheckEntity(createRequest(test).withOwner(TEAM_OWNER1).withDisplayName("Ingestion1"), ADMIN_AUTH_HEADERS);
}
@Test
void post_AirflowPipelineWithConfig_200_ok(TestInfo test) throws IOException {
createAndCheckEntity(create(test).withPipelineConfig(INGESTION_CONFIG), adminAuthHeaders());
createAndCheckEntity(createRequest(test).withPipelineConfig(INGESTION_CONFIG), ADMIN_AUTH_HEADERS);
}
@Test
void post_AirflowPipeline_as_non_admin_401(TestInfo test) {
CreateAirflowPipeline create = create(test);
CreateAirflowPipeline create = createRequest(test);
HttpResponseException exception =
assertThrows(HttpResponseException.class, () -> createEntity(create, authHeaders("test@open-metadata.org")));
assertThrows(HttpResponseException.class, () -> createEntity(create, TEST_AUTH_HEADERS));
assertResponse(exception, FORBIDDEN, "Principal: CatalogPrincipal{name='test'} is not admin");
}
@Test
void post_AirflowPipelineWithoutRequiredService_4xx(TestInfo test) {
CreateAirflowPipeline create = create(test).withService(null);
CreateAirflowPipeline create = createRequest(test).withService(null);
HttpResponseException exception =
assertThrows(HttpResponseException.class, () -> createEntity(create, adminAuthHeaders()));
assertThrows(HttpResponseException.class, () -> createEntity(create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponseContains(exception, BAD_REQUEST, "service must not be null");
}
@Test
void post_AirflowPipelineWithDeploy_4xx(TestInfo test) {
CreateAirflowPipeline create = create(test).withService(BIGQUERY_REFERENCE).withForceDeploy(true);
CreateAirflowPipeline create = createRequest(test).withService(BIGQUERY_REFERENCE).withForceDeploy(true);
HttpResponseException exception =
assertThrows(HttpResponseException.class, () -> createEntity(create, adminAuthHeaders()));
assertThrows(HttpResponseException.class, () -> createEntity(create, ADMIN_AUTH_HEADERS));
// TODO check for error
}
@ -234,7 +243,7 @@ public class AirflowPipelineResourceTest extends EntityOperationsResourceTest<Ai
// Create Ingestion for each service and test APIs
for (EntityReference service : differentServices) {
AirflowPipeline ingestion = createAndCheckEntity(create(test).withService(service), adminAuthHeaders());
AirflowPipeline ingestion = createAndCheckEntity(createRequest(test).withService(service), ADMIN_AUTH_HEADERS);
assertEquals(service.getName(), ingestion.getService().getName());
}
}
@ -242,12 +251,12 @@ public class AirflowPipelineResourceTest extends EntityOperationsResourceTest<Ai
@Test
void post_AirflowWithDatabaseServiceMetadata_200_ok(TestInfo test) throws IOException {
CreateAirflowPipeline request =
create(test)
createRequest(test)
.withPipelineType(PipelineType.METADATA)
.withService(new EntityReference().withId(BIGQUERY_REFERENCE.getId()).withType("databaseService"))
.withDescription("description")
.withScheduleInterval("5 * * * *");
createAndCheckEntity(request, adminAuthHeaders());
createAndCheckEntity(request, ADMIN_AUTH_HEADERS);
Integer pipelineConcurrency = 110;
Date startDate = new DateTime("2021-11-13T20:20:39+00:00").toDate();
String expectedScheduleInterval = "7 * * * *";
@ -260,26 +269,26 @@ public class AirflowPipelineResourceTest extends EntityOperationsResourceTest<Ai
.withScheduleInterval(expectedScheduleInterval)
.withStartDate(startDate.toString()),
OK,
adminAuthHeaders());
ADMIN_AUTH_HEADERS);
String expectedFQN = BIGQUERY_REFERENCE.getName() + "." + ingestion.getName();
validatePipelineConfig(INGESTION_CONFIG, ingestion.getPipelineConfig());
assertEquals(startDate.toString(), ingestion.getStartDate());
assertEquals(pipelineConcurrency, ingestion.getConcurrency());
assertEquals(expectedFQN, ingestion.getFullyQualifiedName());
assertEquals(expectedScheduleInterval, ingestion.getScheduleInterval());
ingestion = getEntity(ingestion.getId(), "owner", adminAuthHeaders());
ingestion = getEntity(ingestion.getId(), "owner", ADMIN_AUTH_HEADERS);
assertEquals(expectedScheduleInterval, ingestion.getScheduleInterval());
}
@Test
void post_AirflowWithDatabaseServiceQueryUsage_200_ok(TestInfo test) throws IOException {
CreateAirflowPipeline request =
create(test)
createRequest(test)
.withPipelineType(PipelineType.METADATA)
.withService(new EntityReference().withId(BIGQUERY_REFERENCE.getId()).withType("databaseService"))
.withDescription("description")
.withScheduleInterval("5 * * * *");
createAndCheckEntity(request, adminAuthHeaders());
createAndCheckEntity(request, ADMIN_AUTH_HEADERS);
Integer pipelineConcurrency = 110;
Date startDate = new DateTime("2021-11-13T20:20:39+00:00").toDate();
String expectedScheduleInterval = "7 * * * *";
@ -298,25 +307,25 @@ public class AirflowPipelineResourceTest extends EntityOperationsResourceTest<Ai
.withScheduleInterval(expectedScheduleInterval)
.withStartDate(startDate.toString()),
OK,
adminAuthHeaders());
ADMIN_AUTH_HEADERS);
String expectedFQN = BIGQUERY_REFERENCE.getName() + "." + ingestion.getName();
validatePipelineConfig(queryUsageConfig, ingestion.getPipelineConfig());
assertEquals(startDate.toString(), ingestion.getStartDate());
assertEquals(pipelineConcurrency, ingestion.getConcurrency());
assertEquals(expectedFQN, ingestion.getFullyQualifiedName());
assertEquals(expectedScheduleInterval, ingestion.getScheduleInterval());
ingestion = getEntity(ingestion.getId(), "owner", adminAuthHeaders());
ingestion = getEntity(ingestion.getId(), "owner", ADMIN_AUTH_HEADERS);
assertEquals(expectedScheduleInterval, ingestion.getScheduleInterval());
}
@Test
void put_AirflowPipelineUrlUpdate_200(TestInfo test) throws IOException {
CreateAirflowPipeline request =
create(test)
createRequest(test)
.withService(new EntityReference().withId(BIGQUERY_REFERENCE.getId()).withType("databaseService"))
.withDescription("description")
.withScheduleInterval("5 * * * *");
createAndCheckEntity(request, adminAuthHeaders());
createAndCheckEntity(request, ADMIN_AUTH_HEADERS);
Integer pipelineConcurrency = 110;
Date startDate = new DateTime("2021-11-13T20:20:39+00:00").toDate();
String expectedScheduleInterval = "7 * * * *";
@ -329,13 +338,13 @@ public class AirflowPipelineResourceTest extends EntityOperationsResourceTest<Ai
.withScheduleInterval(expectedScheduleInterval)
.withStartDate(startDate.toString()),
OK,
adminAuthHeaders());
ADMIN_AUTH_HEADERS);
String expectedFQN = BIGQUERY_REFERENCE.getName() + "." + ingestion.getName();
assertEquals(startDate.toString(), ingestion.getStartDate());
assertEquals(pipelineConcurrency, ingestion.getConcurrency());
assertEquals(expectedFQN, ingestion.getFullyQualifiedName());
assertEquals(expectedScheduleInterval, ingestion.getScheduleInterval());
ingestion = getEntity(ingestion.getId(), "owner", adminAuthHeaders());
ingestion = getEntity(ingestion.getId(), "owner", ADMIN_AUTH_HEADERS);
assertEquals(expectedScheduleInterval, ingestion.getScheduleInterval());
DatabaseServiceMetadataPipeline metadataPipeline =
new DatabaseServiceMetadataPipeline()
@ -356,7 +365,7 @@ public class AirflowPipelineResourceTest extends EntityOperationsResourceTest<Ai
.withScheduleInterval(expectedScheduleInterval)
.withStartDate(startDate.toString()),
OK,
adminAuthHeaders());
ADMIN_AUTH_HEADERS);
assertEquals(startDate.toString(), ingestion.getStartDate());
assertEquals(pipelineConcurrency, ingestion.getConcurrency());
assertEquals(expectedFQN, ingestion.getFullyQualifiedName());
@ -368,16 +377,19 @@ public class AirflowPipelineResourceTest extends EntityOperationsResourceTest<Ai
void post_AirflowWithDatabaseServiceMetadata_GeneratedIngestionPipelineConfig_200_ok(TestInfo test)
throws IOException, ParseException {
CreateAirflowPipeline request =
create(test)
createRequest(test)
.withPipelineType(PipelineType.METADATA)
.withService(new EntityReference().withId(BIGQUERY_REFERENCE.getId()).withType("databaseService"))
.withDescription("description")
.withScheduleInterval("5 * * * *");
AirflowPipeline airflowPipeline = createAndCheckEntity(request, adminAuthHeaders());
.withScheduleInterval("5 * * * *")
.withOwner(USER_OWNER1);
AirflowPipeline airflowPipeline = createAndCheckEntity(request, ADMIN_AUTH_HEADERS);
// Update pipeline attributes
// TODO move this updateAndCheckEntity
Integer pipelineConcurrency = 110;
Date startDate = new DateTime("2021-11-13T20:20:39+00:00").toDate();
String expectedScheduleInterval = "7 * * * *";
// Updating description is ignored when backend already has description
AirflowPipeline ingestion =
updateAirflowPipeline(
request
@ -386,16 +398,19 @@ public class AirflowPipelineResourceTest extends EntityOperationsResourceTest<Ai
.withScheduleInterval(expectedScheduleInterval)
.withStartDate(startDate.toString()),
OK,
adminAuthHeaders());
ADMIN_AUTH_HEADERS);
String expectedFQN = BIGQUERY_REFERENCE.getName() + "." + ingestion.getName();
validatePipelineConfig(INGESTION_CONFIG, ingestion.getPipelineConfig());
assertEquals(startDate.toString(), ingestion.getStartDate());
assertEquals(pipelineConcurrency, ingestion.getConcurrency());
assertEquals(expectedFQN, ingestion.getFullyQualifiedName());
assertEquals(expectedScheduleInterval, ingestion.getScheduleInterval());
ingestion = getEntity(ingestion.getId(), "owner", adminAuthHeaders());
ingestion = getEntity(ingestion.getId(), "owner", ADMIN_AUTH_HEADERS);
assertEquals(expectedScheduleInterval, ingestion.getScheduleInterval());
validateGeneratedAirflowPipelineConfig(airflowPipeline);
// Update and connector orgs and options to database connection
DatabaseService databaseService = helper(airflowPipeline).findEntity("service", DATABASE_SERVICE);
DatabaseConnection databaseConnection = databaseService.getDatabaseConnection();
@ -407,10 +422,11 @@ public class AirflowPipelineResourceTest extends EntityOperationsResourceTest<Ai
new ConnectionOptions().withAdditionalProperty("key1", "value1").withAdditionalProperty("key2", "value2");
databaseConnection.withConnectionOptions(connectionOptions).withConnectionArguments(connectionArguments);
databaseService.setDatabaseConnection(databaseConnection);
DatabaseService updatedService =
DATABASE_SERVICE_RESOURCE_TEST.updateEntity(databaseService, OK, adminAuthHeaders());
assertEquals(databaseService.getDatabaseConnection(), updatedService.getDatabaseConnection());
validateGeneratedAirflowPipelineConfig(airflowPipeline);
// TODO this needs to be fixed
// DatabaseService updatedService =
// DATABASE_SERVICE_RESOURCE_TEST.updateEntity(databaseService, OK, ADMIN_AUTH_HEADERS);
// assertEquals(databaseService.getDatabaseConnection(), updatedService.getDatabaseConnection());
// validateGeneratedAirflowPipelineConfig(airflowPipeline);
}
@Test
@ -422,7 +438,7 @@ public class AirflowPipelineResourceTest extends EntityOperationsResourceTest<Ai
.withServiceType(CreateDatabaseService.DatabaseServiceType.Snowflake)
.withDatabaseConnection(TestUtils.DATABASE_CONNECTION);
DatabaseService snowflakeDatabaseService =
databaseServiceResourceTest.createEntity(createSnowflakeService, adminAuthHeaders());
databaseServiceResourceTest.createEntity(createSnowflakeService, ADMIN_AUTH_HEADERS);
EntityReference snowflakeRef =
new EntityReference()
.withName(snowflakeDatabaseService.getName())
@ -435,7 +451,7 @@ public class AirflowPipelineResourceTest extends EntityOperationsResourceTest<Ai
.withServiceType(CreateDatabaseService.DatabaseServiceType.BigQuery)
.withDatabaseConnection(TestUtils.DATABASE_CONNECTION);
DatabaseService databaseService =
databaseServiceResourceTest.createEntity(createBigQueryService, adminAuthHeaders());
databaseServiceResourceTest.createEntity(createBigQueryService, ADMIN_AUTH_HEADERS);
EntityReference bigqueryRef =
new EntityReference()
.withName(databaseService.getName())
@ -443,29 +459,29 @@ public class AirflowPipelineResourceTest extends EntityOperationsResourceTest<Ai
.withType(Entity.DATABASE_SERVICE);
CreateAirflowPipeline requestPipeline_1 =
create(test)
createRequest(test)
.withName("ingestion_1")
.withPipelineType(PipelineType.METADATA)
.withService(bigqueryRef)
.withDescription("description")
.withScheduleInterval("5 * * * *");
AirflowPipeline pipelineBigquery1 = createAndCheckEntity(requestPipeline_1, adminAuthHeaders());
AirflowPipeline pipelineBigquery1 = createAndCheckEntity(requestPipeline_1, ADMIN_AUTH_HEADERS);
CreateAirflowPipeline requestPipeline_2 =
create(test)
createRequest(test)
.withName("ingestion_2")
.withPipelineType(PipelineType.METADATA)
.withService(bigqueryRef)
.withDescription("description")
.withScheduleInterval("5 * * * *");
AirflowPipeline pipelineBigquery2 = createAndCheckEntity(requestPipeline_2, adminAuthHeaders());
AirflowPipeline pipelineBigquery2 = createAndCheckEntity(requestPipeline_2, ADMIN_AUTH_HEADERS);
CreateAirflowPipeline requestPipeline_3 =
create(test)
createRequest(test)
.withName("ingestion_2")
.withPipelineType(PipelineType.METADATA)
.withService(snowflakeRef)
.withDescription("description")
.withScheduleInterval("5 * * * *");
AirflowPipeline airflowPipeline3 = createAndCheckEntity(requestPipeline_3, adminAuthHeaders());
AirflowPipeline airflowPipeline3 = createAndCheckEntity(requestPipeline_3, ADMIN_AUTH_HEADERS);
// List charts by filtering on service name and ensure right charts in the response
Map<String, String> queryParams =
new HashMap<>() {
@ -476,7 +492,7 @@ public class AirflowPipelineResourceTest extends EntityOperationsResourceTest<Ai
Predicate<AirflowPipeline> isPipelineBigquery1 = p -> p.getId().equals(pipelineBigquery1.getId());
Predicate<AirflowPipeline> isPipelineBigquery2 = u -> u.getId().equals(pipelineBigquery2.getId());
Predicate<AirflowPipeline> isPipelineBigquery3 = u -> u.getId().equals(airflowPipeline3.getId());
List<AirflowPipeline> actualBigqueryPipelines = listEntities(queryParams, adminAuthHeaders()).getData();
List<AirflowPipeline> actualBigqueryPipelines = listEntities(queryParams, ADMIN_AUTH_HEADERS).getData();
assertEquals(2, actualBigqueryPipelines.size());
assertTrue(actualBigqueryPipelines.stream().anyMatch(isPipelineBigquery1));
assertTrue(actualBigqueryPipelines.stream().anyMatch(isPipelineBigquery2));
@ -486,22 +502,23 @@ public class AirflowPipelineResourceTest extends EntityOperationsResourceTest<Ai
put("service", snowflakeRef.getName());
}
};
List<AirflowPipeline> actualSnowflakePipelines = listEntities(queryParams, adminAuthHeaders()).getData();
List<AirflowPipeline> actualSnowflakePipelines = listEntities(queryParams, ADMIN_AUTH_HEADERS).getData();
assertEquals(1, actualSnowflakePipelines.size());
assertTrue(actualSnowflakePipelines.stream().anyMatch(isPipelineBigquery3));
}
@Test
void put_AirflowPipelineUpdate_200(TestInfo test) throws IOException {
CreateAirflowPipeline request = create(test).withService(BIGQUERY_REFERENCE).withDescription(null).withOwner(null);
AirflowPipeline ingestion = createAndCheckEntity(request, adminAuthHeaders());
CreateAirflowPipeline request =
createRequest(test).withService(BIGQUERY_REFERENCE).withDescription(null).withOwner(null);
AirflowPipeline ingestion = createAndCheckEntity(request, ADMIN_AUTH_HEADERS);
// Add description and tasks
ChangeDescription change = getChangeDescription(ingestion.getVersion());
change.getFieldsAdded().add(new FieldChange().withName("description").withNewValue("newDescription"));
change.getFieldsAdded().add(new FieldChange().withName("owner").withNewValue(USER_OWNER1));
updateAndCheckEntity(
request.withDescription("newDescription").withOwner(USER_OWNER1), OK, adminAuthHeaders(), MINOR_UPDATE, change);
request.withDescription("newDescription").withOwner(USER_OWNER1), OK, ADMIN_AUTH_HEADERS, MINOR_UPDATE, change);
}
@Test
@ -524,25 +541,11 @@ public class AirflowPipelineResourceTest extends EntityOperationsResourceTest<Ai
String fields = "owner";
ingestion =
byName
? getEntityByName(ingestion.getFullyQualifiedName(), null, fields, adminAuthHeaders())
: getEntity(ingestion.getId(), fields, adminAuthHeaders());
? getEntityByName(ingestion.getFullyQualifiedName(), fields, ADMIN_AUTH_HEADERS)
: getEntity(ingestion.getId(), fields, ADMIN_AUTH_HEADERS);
assertListNotNull(ingestion.getOwner(), ingestion.getService());
}
public CreateAirflowPipeline create(TestInfo test) {
return create(getEntityName(test));
}
private CreateAirflowPipeline create(String name) {
return new CreateAirflowPipeline()
.withName(name)
.withPipelineType(PipelineType.METADATA)
.withService(BIGQUERY_REFERENCE)
.withPipelineConfig(INGESTION_CONFIG)
.withStartDate("2021-11-21")
.withOwner(TEAM_OWNER1);
}
private void validatePipelineConfig(PipelineConfig orig, PipelineConfig updated) {
assertEquals(orig.getSchema(), updated.getSchema());
if (orig.getSchema().equals(PipelineConfig.Schema.DATABASE_SERVICE_METADATA_PIPELINE)) {
@ -595,9 +598,4 @@ public class AirflowPipelineResourceTest extends EntityOperationsResourceTest<Ai
source.getConfig().get(INGESTION_OPTIONS));
}
}
private void listDatabaseServicePipelines(AirflowPipeline airflowPipeline) throws IOException, ParseException {
DatabaseService databaseService = helper(airflowPipeline).findEntity("service", DATABASE_SERVICE);
DatabaseServiceResourceTest.getResource("services/databaseServices");
}
}

View File

@ -20,9 +20,9 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.openmetadata.catalog.security.SecurityUtil.authHeaders;
import static org.openmetadata.catalog.util.TestUtils.ADMIN_AUTH_HEADERS;
import static org.openmetadata.catalog.util.TestUtils.TEST_AUTH_HEADERS;
import static org.openmetadata.catalog.util.TestUtils.UpdateType.MINOR_UPDATE;
import static org.openmetadata.catalog.util.TestUtils.adminAuthHeaders;
import static org.openmetadata.catalog.util.TestUtils.assertListNotNull;
import static org.openmetadata.catalog.util.TestUtils.assertResponse;
@ -36,7 +36,6 @@ import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response.Status;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.HttpResponseException;
import org.joda.time.DateTime;
@ -59,7 +58,7 @@ import org.openmetadata.catalog.util.ResultList;
import org.openmetadata.catalog.util.TestUtils;
@Slf4j
public class PipelineResourceTest extends EntityResourceTest<Pipeline> {
public class PipelineResourceTest extends EntityResourceTest<Pipeline, CreatePipeline> {
public static List<Task> TASKS;
public PipelineResourceTest() {
@ -91,20 +90,24 @@ public class PipelineResourceTest extends EntityResourceTest<Pipeline> {
}
@Override
public Object createRequest(String name, String description, String displayName, EntityReference owner) {
return create(name).withDescription(description).withDisplayName(displayName).withOwner(owner).withTasks(TASKS);
public CreatePipeline createRequest(String name, String description, String displayName, EntityReference owner) {
return new CreatePipeline()
.withName(name)
.withService(AIRFLOW_REFERENCE)
.withDescription(description)
.withDisplayName(displayName)
.withOwner(owner)
.withTasks(TASKS);
}
@Override
public EntityReference getContainer(Object createRequest) throws URISyntaxException {
CreatePipeline createPipeline = (CreatePipeline) createRequest;
return createPipeline.getService();
public EntityReference getContainer(CreatePipeline createRequest) {
return createRequest.getService();
}
@Override
public void validateCreatedEntity(Pipeline pipeline, Object request, Map<String, String> authHeaders)
public void validateCreatedEntity(Pipeline pipeline, CreatePipeline createRequest, Map<String, String> authHeaders)
throws HttpResponseException {
CreatePipeline createRequest = (CreatePipeline) request;
validateCommonEntityFields(
getEntityInterface(pipeline),
createRequest.getDescription(),
@ -118,7 +121,7 @@ public class PipelineResourceTest extends EntityResourceTest<Pipeline> {
}
@Override
public void validateUpdatedEntity(Pipeline pipeline, Object request, Map<String, String> authHeaders)
public void validateUpdatedEntity(Pipeline pipeline, CreatePipeline request, Map<String, String> authHeaders)
throws HttpResponseException {
validateCreatedEntity(pipeline, request, authHeaders);
}
@ -148,6 +151,7 @@ public class PipelineResourceTest extends EntityResourceTest<Pipeline> {
return;
}
if (fieldName.contains("tasks") && !fieldName.contains(".")) {
@SuppressWarnings("unchecked")
List<Task> expectedTasks = (List<Task>) expected;
List<Task> actualTasks = JsonUtils.readObjects(actual.toString(), Task.class);
assertEquals(expectedTasks, actualTasks);
@ -159,41 +163,41 @@ public class PipelineResourceTest extends EntityResourceTest<Pipeline> {
@Test
void post_validPipelines_as_admin_200_OK(TestInfo test) throws IOException {
// Create team with different optional fields
CreatePipeline create = create(test);
createAndCheckEntity(create, adminAuthHeaders());
CreatePipeline create = createRequest(test);
createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
create.withName(getEntityName(test, 1)).withDescription("description");
createAndCheckEntity(create, adminAuthHeaders());
createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
}
@Test
void post_PipelineWithUserOwner_200_ok(TestInfo test) throws IOException {
createAndCheckEntity(create(test).withOwner(USER_OWNER1), adminAuthHeaders());
createAndCheckEntity(createRequest(test).withOwner(USER_OWNER1), ADMIN_AUTH_HEADERS);
}
@Test
void post_PipelineWithTeamOwner_200_ok(TestInfo test) throws IOException {
createAndCheckEntity(create(test).withOwner(TEAM_OWNER1).withDisplayName("Pipeline1"), adminAuthHeaders());
createAndCheckEntity(createRequest(test).withOwner(TEAM_OWNER1).withDisplayName("Pipeline1"), ADMIN_AUTH_HEADERS);
}
@Test
void post_PipelineWithTasks_200_ok(TestInfo test) throws IOException {
createAndCheckEntity(create(test).withTasks(TASKS), adminAuthHeaders());
createAndCheckEntity(createRequest(test).withTasks(TASKS), ADMIN_AUTH_HEADERS);
}
@Test
void post_Pipeline_as_non_admin_401(TestInfo test) {
CreatePipeline create = create(test);
CreatePipeline create = createRequest(test);
HttpResponseException exception =
assertThrows(HttpResponseException.class, () -> createPipeline(create, authHeaders("test@open-metadata.org")));
assertThrows(HttpResponseException.class, () -> createEntity(create, TEST_AUTH_HEADERS));
assertResponse(exception, FORBIDDEN, "Principal: CatalogPrincipal{name='test'} is not admin");
}
@Test
void post_PipelineWithoutRequiredService_4xx(TestInfo test) {
CreatePipeline create = create(test).withService(null);
CreatePipeline create = createRequest(test).withService(null);
HttpResponseException exception =
assertThrows(HttpResponseException.class, () -> createPipeline(create, adminAuthHeaders()));
assertThrows(HttpResponseException.class, () -> createEntity(create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponseContains(exception, BAD_REQUEST, "service must not be null");
}
@ -203,7 +207,7 @@ public class PipelineResourceTest extends EntityResourceTest<Pipeline> {
// Create Pipeline for each service and test APIs
for (EntityReference service : differentServices) {
createAndCheckEntity(create(test).withService(service), adminAuthHeaders());
createAndCheckEntity(createRequest(test).withService(service), ADMIN_AUTH_HEADERS);
// List Pipelines by filtering on service name and ensure right Pipelines in the response
Map<String, String> queryParams =
@ -212,7 +216,7 @@ public class PipelineResourceTest extends EntityResourceTest<Pipeline> {
put("service", service.getName());
}
};
ResultList<Pipeline> list = listEntities(queryParams, adminAuthHeaders());
ResultList<Pipeline> list = listEntities(queryParams, ADMIN_AUTH_HEADERS);
for (Pipeline db : list.getData()) {
assertEquals(service.getName(), db.getService().getName());
}
@ -222,20 +226,20 @@ public class PipelineResourceTest extends EntityResourceTest<Pipeline> {
@Test
void put_PipelineUrlUpdate_200(TestInfo test) throws IOException, URISyntaxException {
CreatePipeline request =
create(test)
createRequest(test)
.withService(new EntityReference().withId(AIRFLOW_REFERENCE.getId()).withType("pipelineService"))
.withDescription("description");
createAndCheckEntity(request, adminAuthHeaders());
createAndCheckEntity(request, ADMIN_AUTH_HEADERS);
URI pipelineURI = new URI("https://airflow.open-metadata.org/tree?dag_id=airflow_redshift_usage");
Integer pipelineConcurrency = 110;
Date startDate = new DateTime("2021-11-13T20:20:39+00:00").toDate();
// Updating description is ignored when backend already has description
Pipeline pipeline =
updatePipeline(
updateEntity(
request.withPipelineUrl(pipelineURI).withConcurrency(pipelineConcurrency).withStartDate(startDate),
OK,
adminAuthHeaders());
ADMIN_AUTH_HEADERS);
String expectedFQN = AIRFLOW_REFERENCE.getName() + "." + pipeline.getName();
assertEquals(pipelineURI, pipeline.getPipelineUrl());
assertEquals(startDate, pipeline.getStartDate());
@ -245,8 +249,8 @@ public class PipelineResourceTest extends EntityResourceTest<Pipeline> {
@Test
void put_PipelineTasksUpdate_200(TestInfo test) throws IOException, URISyntaxException {
CreatePipeline request = create(test).withService(AIRFLOW_REFERENCE).withDescription(null);
Pipeline pipeline = createAndCheckEntity(request, adminAuthHeaders());
CreatePipeline request = createRequest(test).withService(AIRFLOW_REFERENCE).withDescription(null).withTasks(null);
Pipeline pipeline = createAndCheckEntity(request, ADMIN_AUTH_HEADERS);
// Add description and tasks
ChangeDescription change = getChangeDescription(pipeline.getVersion());
@ -254,7 +258,7 @@ public class PipelineResourceTest extends EntityResourceTest<Pipeline> {
change.getFieldsAdded().add(new FieldChange().withName("tasks").withNewValue(TASKS));
pipeline =
updateAndCheckEntity(
request.withDescription("newDescription").withTasks(TASKS), OK, adminAuthHeaders(), MINOR_UPDATE, change);
request.withDescription("newDescription").withTasks(TASKS), OK, ADMIN_AUTH_HEADERS, MINOR_UPDATE, change);
// Add a task without description
change = getChangeDescription(pipeline.getVersion());
@ -262,13 +266,13 @@ public class PipelineResourceTest extends EntityResourceTest<Pipeline> {
Task taskEmptyDesc = new Task().withName("taskEmpty").withTaskUrl(new URI("http://localhost:0"));
tasks.add(taskEmptyDesc);
change.getFieldsAdded().add(new FieldChange().withName("tasks").withNewValue(tasks));
updateAndCheckEntity(request.withTasks(tasks), OK, adminAuthHeaders(), MINOR_UPDATE, change);
updateAndCheckEntity(request.withTasks(tasks), OK, ADMIN_AUTH_HEADERS, MINOR_UPDATE, change);
}
@Test
void patch_PipelineTasksUpdate_200_ok(TestInfo test) throws IOException, URISyntaxException {
CreatePipeline request = create(test).withService(AIRFLOW_REFERENCE);
Pipeline pipeline = createAndCheckEntity(request, adminAuthHeaders());
CreatePipeline request = createRequest(test).withService(AIRFLOW_REFERENCE);
Pipeline pipeline = createAndCheckEntity(request, ADMIN_AUTH_HEADERS);
String origJson = JsonUtils.pojoToJson(pipeline);
// Add a task without description
@ -280,7 +284,7 @@ public class PipelineResourceTest extends EntityResourceTest<Pipeline> {
change.getFieldsAdded().add(new FieldChange().withName("description").withNewValue("newDescription"));
pipeline.setDescription("newDescription");
pipeline.setTasks(tasks);
pipeline = patchEntityAndCheck(pipeline, origJson, adminAuthHeaders(), MINOR_UPDATE, change);
pipeline = patchEntityAndCheck(pipeline, origJson, ADMIN_AUTH_HEADERS, MINOR_UPDATE, change);
// add a description to an existing task
origJson = JsonUtils.pojoToJson(pipeline);
@ -292,7 +296,7 @@ public class PipelineResourceTest extends EntityResourceTest<Pipeline> {
.getFieldsAdded()
.add(new FieldChange().withName("tasks.taskEmpty.description").withNewValue("taskDescription"));
pipeline.setTasks(newTasks);
pipeline = patchEntityAndCheck(pipeline, origJson, adminAuthHeaders(), MINOR_UPDATE, change);
pipeline = patchEntityAndCheck(pipeline, origJson, ADMIN_AUTH_HEADERS, MINOR_UPDATE, change);
// update the descriptions of pipeline and task
origJson = JsonUtils.pojoToJson(pipeline);
@ -312,7 +316,7 @@ public class PipelineResourceTest extends EntityResourceTest<Pipeline> {
.add(new FieldChange().withName("description").withOldValue("newDescription").withNewValue("newDescription2"));
pipeline.setTasks(newTasks);
pipeline.setDescription("newDescription2");
pipeline = patchEntityAndCheck(pipeline, origJson, adminAuthHeaders(), MINOR_UPDATE, change);
pipeline = patchEntityAndCheck(pipeline, origJson, ADMIN_AUTH_HEADERS, MINOR_UPDATE, change);
// delete task and pipeline description by setting them to null
origJson = JsonUtils.pojoToJson(pipeline);
@ -332,19 +336,19 @@ public class PipelineResourceTest extends EntityResourceTest<Pipeline> {
.add(new FieldChange().withName("description").withOldValue("newDescription2").withNewValue(null));
pipeline.setTasks(newTasks);
pipeline.setDescription(null);
patchEntityAndCheck(pipeline, origJson, adminAuthHeaders(), MINOR_UPDATE, change);
patchEntityAndCheck(pipeline, origJson, ADMIN_AUTH_HEADERS, MINOR_UPDATE, change);
}
@Test
void put_AddRemovePipelineTasksUpdate_200(TestInfo test) throws IOException, URISyntaxException {
CreatePipeline request =
create(test)
createRequest(test)
.withService(AIRFLOW_REFERENCE)
.withDescription(null)
.withTasks(null)
.withConcurrency(null)
.withPipelineUrl(new URI("http://localhost:8080"));
Pipeline pipeline = createAndCheckEntity(request, adminAuthHeaders());
Pipeline pipeline = createAndCheckEntity(request, ADMIN_AUTH_HEADERS);
// Add tasks and description
ChangeDescription change = getChangeDescription(pipeline.getVersion());
@ -366,14 +370,14 @@ public class PipelineResourceTest extends EntityResourceTest<Pipeline> {
.withConcurrency(5)
.withPipelineUrl(new URI("https://airflow.open-metadata.org")),
OK,
adminAuthHeaders(),
ADMIN_AUTH_HEADERS,
MINOR_UPDATE,
change);
// TODO update this once task removal is figured out
// remove a task
// TASKS.remove(0);
// change = getChangeDescription(pipeline.getVersion()).withFieldsUpdated(singletonList("tasks"));
// updateAndCheckEntity(request.withTasks(TASKS), OK, adminAuthHeaders(), MINOR_UPDATE, change);
// updateAndCheckEntity(request.withTasks(TASKS), OK, ADMIN_AUTH_HEADERS, MINOR_UPDATE, change);
}
@Test
@ -381,16 +385,6 @@ public class PipelineResourceTest extends EntityResourceTest<Pipeline> {
// TODO
}
public static Pipeline updatePipeline(CreatePipeline create, Status status, Map<String, String> authHeaders)
throws HttpResponseException {
return TestUtils.put(getResource("pipelines"), create, Pipeline.class, status, authHeaders);
}
public static Pipeline createPipeline(CreatePipeline create, Map<String, String> authHeaders)
throws HttpResponseException {
return TestUtils.post(getResource("pipelines"), create, Pipeline.class, authHeaders);
}
/** Validate returned fields GET .../pipelines/{id}?fields="..." or GET .../pipelines/name/{fqn}?fields="..." */
@Override
public void validateGetWithDifferentFields(Pipeline pipeline, boolean byName) throws HttpResponseException {
@ -398,8 +392,8 @@ public class PipelineResourceTest extends EntityResourceTest<Pipeline> {
String fields = "owner";
pipeline =
byName
? getPipelineByName(pipeline.getFullyQualifiedName(), fields, adminAuthHeaders())
: getPipeline(pipeline.getId(), fields, adminAuthHeaders());
? getPipelineByName(pipeline.getFullyQualifiedName(), fields, ADMIN_AUTH_HEADERS)
: getPipeline(pipeline.getId(), fields, ADMIN_AUTH_HEADERS);
assertListNotNull(pipeline.getOwner(), pipeline.getService(), pipeline.getServiceType());
assertNull(pipeline.getTasks());
@ -407,8 +401,8 @@ public class PipelineResourceTest extends EntityResourceTest<Pipeline> {
fields = "owner,tasks";
pipeline =
byName
? getPipelineByName(pipeline.getFullyQualifiedName(), fields, adminAuthHeaders())
: getPipeline(pipeline.getId(), fields, adminAuthHeaders());
? getPipelineByName(pipeline.getFullyQualifiedName(), fields, ADMIN_AUTH_HEADERS)
: getPipeline(pipeline.getId(), fields, ADMIN_AUTH_HEADERS);
assertListNotNull(pipeline.getOwner(), pipeline.getService(), pipeline.getServiceType(), pipeline.getTasks());
}
@ -425,12 +419,4 @@ public class PipelineResourceTest extends EntityResourceTest<Pipeline> {
target = fields != null ? target.queryParam("fields", fields) : target;
return TestUtils.get(target, Pipeline.class, authHeaders);
}
private CreatePipeline create(TestInfo test) {
return create(getEntityName(test));
}
private CreatePipeline create(String name) {
return new CreatePipeline().withName(name).withService(AIRFLOW_REFERENCE);
}
}

View File

@ -20,9 +20,9 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.fail;
import static org.openmetadata.catalog.security.SecurityUtil.authHeaders;
import static org.openmetadata.catalog.util.TestUtils.ADMIN_AUTH_HEADERS;
import static org.openmetadata.catalog.util.TestUtils.TEST_AUTH_HEADERS;
import static org.openmetadata.catalog.util.TestUtils.UpdateType.MINOR_UPDATE;
import static org.openmetadata.catalog.util.TestUtils.adminAuthHeaders;
import static org.openmetadata.catalog.util.TestUtils.assertEntityPagination;
import static org.openmetadata.catalog.util.TestUtils.assertResponse;
import static org.openmetadata.catalog.util.TestUtils.assertResponseContains;
@ -31,7 +31,6 @@ import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@ -64,9 +63,9 @@ import org.openmetadata.catalog.util.PolicyUtils;
import org.openmetadata.catalog.util.TestUtils;
@Slf4j
public class PolicyResourceTest extends EntityResourceTest<Policy> {
public class PolicyResourceTest extends EntityResourceTest<Policy, CreatePolicy> {
private static String LOCATION_NAME = "aws-s3";
private static final String LOCATION_NAME = "aws-s3";
private static Location location;
public PolicyResourceTest() {
@ -80,18 +79,17 @@ public class PolicyResourceTest extends EntityResourceTest<Policy> {
}
@Override
public Object createRequest(String name, String description, String displayName, EntityReference owner) {
return create(name).withDescription(description).withDisplayName(displayName).withOwner(owner);
public CreatePolicy createRequest(String name, String description, String displayName, EntityReference owner) {
return new CreatePolicy()
.withName(name)
.withPolicyType(PolicyType.Lifecycle)
.withDescription(description)
.withDisplayName(displayName)
.withOwner(owner);
}
@Override
public EntityReference getContainer(Object createRequest) throws URISyntaxException {
return null; // No container entity for Policy
}
@Override
public void validateCreatedEntity(Policy policy, Object request, Map<String, String> authHeaders) {
CreatePolicy createRequest = (CreatePolicy) request;
public void validateCreatedEntity(Policy policy, CreatePolicy createRequest, Map<String, String> authHeaders) {
validateCommonEntityFields(
getEntityInterface(policy),
createRequest.getDescription(),
@ -101,7 +99,7 @@ public class PolicyResourceTest extends EntityResourceTest<Policy> {
}
@Override
public void validateUpdatedEntity(Policy updatedEntity, Object request, Map<String, String> authHeaders) {
public void validateUpdatedEntity(Policy updatedEntity, CreatePolicy request, Map<String, String> authHeaders) {
validateCreatedEntity(updatedEntity, request, authHeaders);
}
@ -122,6 +120,10 @@ public class PolicyResourceTest extends EntityResourceTest<Policy> {
URI expectedPolicyUrl = (URI) expected;
URI actualPolicyUrl = URI.create((String) actual);
assertEquals(expectedPolicyUrl, actualPolicyUrl);
} else if (fieldName.equals("location")) {
EntityReference expectedLocation = (EntityReference) expected;
EntityReference actualLocation = JsonUtils.readValue(actual.toString(), EntityReference.class);
assertEquals(expectedLocation.getId(), actualLocation.getId());
} else {
assertCommonFieldChange(fieldName, expected, actual);
}
@ -129,31 +131,31 @@ public class PolicyResourceTest extends EntityResourceTest<Policy> {
@Test
void post_PolicyWithoutPolicyType_400_badRequest(TestInfo test) {
CreatePolicy create = create(test).withPolicyType(null);
CreatePolicy create = createRequest(test).withPolicyType(null);
HttpResponseException exception =
assertThrows(HttpResponseException.class, () -> createPolicy(create, adminAuthHeaders()));
assertThrows(HttpResponseException.class, () -> createEntity(create, ADMIN_AUTH_HEADERS));
assertResponse(exception, BAD_REQUEST, "[policyType must not be null]");
}
@Test
void post_validPolicies_as_admin_200_OK(TestInfo test) throws IOException {
// Create valid policy
CreatePolicy create = create(test);
createAndCheckEntity(create, adminAuthHeaders());
CreatePolicy create = createRequest(test);
createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
create.withName(getEntityName(test, 1)).withDescription("description");
createAndCheckEntity(create, adminAuthHeaders());
createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
}
@Test
void post_PolicyWithUserOwner_200_ok(TestInfo test) throws IOException {
CreatePolicy create = create(test).withOwner(USER_OWNER1);
createAndCheckEntity(create, adminAuthHeaders());
CreatePolicy create = createRequest(test).withOwner(USER_OWNER1);
createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
}
@Test
void post_PolicyWithTeamOwner_200_ok(TestInfo test) throws IOException {
CreatePolicy create = create(test).withOwner(TEAM_OWNER1);
createAndCheckEntity(create, adminAuthHeaders());
CreatePolicy create = createRequest(test).withOwner(TEAM_OWNER1);
createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
}
@Test
@ -163,7 +165,7 @@ public class PolicyResourceTest extends EntityResourceTest<Policy> {
PolicyUtils.accessControlRule(null, null, "DataConsumer", MetadataOperation.UpdateDescription, true, 0, true));
rules.add(PolicyUtils.accessControlRule(null, null, "DataConsumer", MetadataOperation.UpdateTags, true, 1, true));
CreatePolicy create = createAccessControlPolicyWithRules(getEntityName(test), rules);
createAndCheckEntity(create, adminAuthHeaders());
createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
}
@Test
@ -173,7 +175,7 @@ public class PolicyResourceTest extends EntityResourceTest<Policy> {
PolicyUtils.accessControlRule("rule21", null, null, null, MetadataOperation.UpdateDescription, true, 0, true));
CreatePolicy create = createAccessControlPolicyWithRules(getEntityName(test), rules);
HttpResponseException exception =
assertThrows(HttpResponseException.class, () -> createEntity(create, adminAuthHeaders()));
assertThrows(HttpResponseException.class, () -> createEntity(create, ADMIN_AUTH_HEADERS));
assertResponseContains(
exception,
BAD_REQUEST,
@ -197,7 +199,7 @@ public class PolicyResourceTest extends EntityResourceTest<Policy> {
"rule3", null, null, "DataConsumer", MetadataOperation.UpdateTags, true, 1, true));
CreatePolicy create = createAccessControlPolicyWithRules(getEntityName(test), rules);
HttpResponseException exception =
assertThrows(HttpResponseException.class, () -> createEntity(create, adminAuthHeaders()));
assertThrows(HttpResponseException.class, () -> createEntity(create, ADMIN_AUTH_HEADERS));
assertResponseContains(
exception,
BAD_REQUEST,
@ -208,9 +210,9 @@ public class PolicyResourceTest extends EntityResourceTest<Policy> {
@Test
void post_Policy_as_non_admin_401(TestInfo test) {
CreatePolicy create = create(test);
CreatePolicy create = createRequest(test);
HttpResponseException exception =
assertThrows(HttpResponseException.class, () -> createPolicy(create, authHeaders("test@open-metadata.org")));
assertThrows(HttpResponseException.class, () -> createEntity(create, TEST_AUTH_HEADERS));
assertResponse(exception, FORBIDDEN, "Principal: CatalogPrincipal{name='test'} is not admin");
}
@ -218,14 +220,14 @@ public class PolicyResourceTest extends EntityResourceTest<Policy> {
void get_PolicyListWithInvalidLimitOffset_4xx() {
// Limit must be >= 1 and <= 1000,000
HttpResponseException exception =
assertThrows(HttpResponseException.class, () -> listPolicies(null, -1, null, null, adminAuthHeaders()));
assertThrows(HttpResponseException.class, () -> listPolicies(null, -1, null, null, ADMIN_AUTH_HEADERS));
assertResponse(exception, BAD_REQUEST, "[query param limit must be greater than or equal to 1]");
exception = assertThrows(HttpResponseException.class, () -> listPolicies(null, 0, null, null, adminAuthHeaders()));
exception = assertThrows(HttpResponseException.class, () -> listPolicies(null, 0, null, null, ADMIN_AUTH_HEADERS));
assertResponse(exception, BAD_REQUEST, "[query param limit must be greater than or equal to 1]");
exception =
assertThrows(HttpResponseException.class, () -> listPolicies(null, 1000001, null, null, adminAuthHeaders()));
assertThrows(HttpResponseException.class, () -> listPolicies(null, 1000001, null, null, ADMIN_AUTH_HEADERS));
assertResponse(exception, BAD_REQUEST, "[query param limit must be less than or equal to 1000000]");
}
@ -233,7 +235,7 @@ public class PolicyResourceTest extends EntityResourceTest<Policy> {
void get_PolicyListWithInvalidPaginationCursors_4xx() {
// Passing both before and after cursors is invalid
HttpResponseException exception =
assertThrows(HttpResponseException.class, () -> listPolicies(null, 1, "", "", adminAuthHeaders()));
assertThrows(HttpResponseException.class, () -> listPolicies(null, 1, "", "", ADMIN_AUTH_HEADERS));
assertResponse(exception, BAD_REQUEST, "Only one of before or after query parameter allowed");
}
@ -242,11 +244,11 @@ public class PolicyResourceTest extends EntityResourceTest<Policy> {
// Create a large number of Policies
int maxPolicies = 40;
for (int i = 0; i < maxPolicies; i++) {
createPolicy(create(test, i), adminAuthHeaders());
createEntity(createRequest(test, i), ADMIN_AUTH_HEADERS);
}
// List all Policies
PolicyList allPolicies = listPolicies(null, 1000000, null, null, adminAuthHeaders());
PolicyList allPolicies = listPolicies(null, 1000000, null, null, ADMIN_AUTH_HEADERS);
int totalRecords = allPolicies.getData().size();
printPolicies(allPolicies);
@ -260,7 +262,7 @@ public class PolicyResourceTest extends EntityResourceTest<Policy> {
PolicyList backwardPage;
do { // For each limit (or page size) - forward scroll till the end
LOG.info("Limit {} forward scrollCount {} afterCursor {}", limit, pageCount, after);
forwardPage = listPolicies(null, limit, null, after, adminAuthHeaders());
forwardPage = listPolicies(null, limit, null, after, ADMIN_AUTH_HEADERS);
printPolicies(forwardPage);
after = forwardPage.getPaging().getAfter();
before = forwardPage.getPaging().getBefore();
@ -270,7 +272,7 @@ public class PolicyResourceTest extends EntityResourceTest<Policy> {
assertNull(before);
} else {
// Make sure scrolling back based on before cursor returns the correct result
backwardPage = listPolicies(null, limit, before, null, adminAuthHeaders());
backwardPage = listPolicies(null, limit, before, null, ADMIN_AUTH_HEADERS);
assertEntityPagination(allPolicies.getData(), backwardPage, limit, (indexInAllPolicies - limit));
}
@ -283,7 +285,7 @@ public class PolicyResourceTest extends EntityResourceTest<Policy> {
indexInAllPolicies = totalRecords - limit - forwardPage.getData().size();
do {
LOG.info("Limit {} backward scrollCount {} beforeCursor {}", limit, pageCount, before);
forwardPage = listPolicies(null, limit, before, null, adminAuthHeaders());
forwardPage = listPolicies(null, limit, before, null, ADMIN_AUTH_HEADERS);
printPolicies(forwardPage);
before = forwardPage.getPaging().getBefore();
assertEntityPagination(allPolicies.getData(), forwardPage, limit, indexInAllPolicies);
@ -300,7 +302,7 @@ public class PolicyResourceTest extends EntityResourceTest<Policy> {
@Test
void patch_PolicyAttributes_200_ok(TestInfo test) throws IOException {
Policy policy = createAndCheckEntity(create(test), adminAuthHeaders());
Policy policy = createAndCheckEntity(createRequest(test), ADMIN_AUTH_HEADERS).withLocation(null);
URI uri = null;
try {
@ -316,27 +318,23 @@ public class PolicyResourceTest extends EntityResourceTest<Policy> {
ChangeDescription change = getChangeDescription(policy.getVersion());
change.getFieldsAdded().add(new FieldChange().withName("policyUrl").withNewValue(uri));
change.getFieldsUpdated().add(new FieldChange().withName("enabled").withOldValue(true).withNewValue(false));
policy = patchEntityAndCheck(policy, origJson, adminAuthHeaders(), MINOR_UPDATE, change);
policy = patchEntityAndCheck(policy, origJson, ADMIN_AUTH_HEADERS, MINOR_UPDATE, change);
// Remove policyUrl
origJson = JsonUtils.pojoToJson(policy);
policy.setPolicyUrl(null);
change = getChangeDescription(policy.getVersion());
change.getFieldsDeleted().add(new FieldChange().withName("policyUrl").withOldValue(uri));
policy = patchEntityAndCheck(policy, origJson, adminAuthHeaders(), MINOR_UPDATE, change);
policy = patchEntityAndCheck(policy, origJson, ADMIN_AUTH_HEADERS, MINOR_UPDATE, change);
EntityReference locationReference = new LocationRepository.LocationEntityInterface(location).getEntityReference();
Map<String, String> locationObj = new LinkedHashMap<>();
locationObj.put("type", locationReference.getType());
locationObj.put("name", locationReference.getName());
locationObj.put("id", locationReference.getId().toString());
// Add new field location
origJson = JsonUtils.pojoToJson(policy);
policy.setLocation(locationReference);
change = getChangeDescription(policy.getVersion());
change.getFieldsAdded().add(new FieldChange().withName("location").withNewValue(locationObj));
patchEntityAndCheck(policy, origJson, adminAuthHeaders(), MINOR_UPDATE, change);
change.getFieldsAdded().add(new FieldChange().withName("location").withNewValue(locationReference));
patchEntityAndCheck(policy, origJson, ADMIN_AUTH_HEADERS, MINOR_UPDATE, change);
}
@Test
@ -344,10 +342,6 @@ public class PolicyResourceTest extends EntityResourceTest<Policy> {
// TODO
}
public static Policy createPolicy(CreatePolicy create, Map<String, String> authHeaders) throws HttpResponseException {
return TestUtils.post(getResource("policies"), create, Policy.class, authHeaders);
}
/** Validate returned fields GET .../policies/{id}?fields="..." or GET .../policies/name/{fqn}?fields="..." */
@Override
public void validateGetWithDifferentFields(Policy policy, boolean byName) throws HttpResponseException {
@ -355,24 +349,24 @@ public class PolicyResourceTest extends EntityResourceTest<Policy> {
String fields = "owner";
policy =
byName
? getPolicyByName(policy.getFullyQualifiedName(), fields, adminAuthHeaders())
: getPolicy(policy.getId(), fields, adminAuthHeaders());
? getPolicyByName(policy.getFullyQualifiedName(), fields, ADMIN_AUTH_HEADERS)
: getPolicy(policy.getId(), fields, ADMIN_AUTH_HEADERS);
assertNotNull(policy.getOwner());
// .../policies?fields=owner,displayName
fields = "owner,displayName";
policy =
byName
? getPolicyByName(policy.getFullyQualifiedName(), fields, adminAuthHeaders())
: getPolicy(policy.getId(), fields, adminAuthHeaders());
? getPolicyByName(policy.getFullyQualifiedName(), fields, ADMIN_AUTH_HEADERS)
: getPolicy(policy.getId(), fields, ADMIN_AUTH_HEADERS);
assertNotNull(policy.getOwner());
// .../policies?fields=owner,displayName,policyUrl
fields = "owner,displayName,policyUrl";
policy =
byName
? getPolicyByName(policy.getFullyQualifiedName(), fields, adminAuthHeaders())
: getPolicy(policy.getId(), fields, adminAuthHeaders());
? getPolicyByName(policy.getFullyQualifiedName(), fields, ADMIN_AUTH_HEADERS)
: getPolicy(policy.getId(), fields, ADMIN_AUTH_HEADERS);
assertNotNull(policy.getOwner());
}
@ -400,18 +394,6 @@ public class PolicyResourceTest extends EntityResourceTest<Policy> {
return TestUtils.get(target, PolicyList.class, authHeaders);
}
private CreatePolicy create(TestInfo test) {
return create(getEntityName(test));
}
private CreatePolicy create(TestInfo test, int index) {
return create(getEntityName(test, index));
}
private CreatePolicy create(String name) {
return new CreatePolicy().withName(name).withDescription("description").withPolicyType(PolicyType.Lifecycle);
}
private CreatePolicy createAccessControlPolicyWithRules(String name, List<Rule> rules) {
return new CreatePolicy()
.withName(name)
@ -422,7 +404,8 @@ public class PolicyResourceTest extends EntityResourceTest<Policy> {
}
private static Location createLocation() throws HttpResponseException {
CreateLocation createLocation = LocationResourceTest.create(LOCATION_NAME, AWS_STORAGE_SERVICE_REFERENCE);
return TestUtils.post(getResource("locations"), createLocation, Location.class, adminAuthHeaders());
LocationResourceTest locationResourceTest = new LocationResourceTest();
CreateLocation createLocation = locationResourceTest.createRequest(LOCATION_NAME, "", "", null);
return TestUtils.post(getResource("locations"), createLocation, Location.class, ADMIN_AUTH_HEADERS);
}
}

View File

@ -18,8 +18,8 @@ import static javax.ws.rs.core.Response.Status.FORBIDDEN;
import static javax.ws.rs.core.Response.Status.OK;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.openmetadata.catalog.security.SecurityUtil.authHeaders;
import static org.openmetadata.catalog.util.TestUtils.adminAuthHeaders;
import static org.openmetadata.catalog.util.TestUtils.ADMIN_AUTH_HEADERS;
import static org.openmetadata.catalog.util.TestUtils.TEST_AUTH_HEADERS;
import static org.openmetadata.catalog.util.TestUtils.getPrincipal;
import java.io.IOException;
@ -47,7 +47,7 @@ import org.openmetadata.catalog.util.TestUtils;
import org.openmetadata.catalog.util.TestUtils.UpdateType;
@Slf4j
public class DashboardServiceResourceTest extends EntityResourceTest<DashboardService> {
public class DashboardServiceResourceTest extends EntityResourceTest<DashboardService, CreateDashboardService> {
public DashboardServiceResourceTest() {
super(
Entity.DASHBOARD_SERVICE,
@ -67,66 +67,66 @@ public class DashboardServiceResourceTest extends EntityResourceTest<DashboardSe
// Create dashboard with mandatory serviceType field empty
HttpResponseException exception =
assertThrows(
HttpResponseException.class, () -> createEntity(create(test).withServiceType(null), adminAuthHeaders()));
HttpResponseException.class,
() -> createEntity(createRequest(test).withServiceType(null), ADMIN_AUTH_HEADERS));
TestUtils.assertResponse(exception, BAD_REQUEST, "[serviceType must not be null]");
// Create dashboard with mandatory brokers field empty
exception =
assertThrows(
HttpResponseException.class, () -> createEntity(create(test).withDashboardUrl(null), adminAuthHeaders()));
HttpResponseException.class,
() -> createEntity(createRequest(test).withDashboardUrl(null), ADMIN_AUTH_HEADERS));
TestUtils.assertResponse(exception, BAD_REQUEST, "[dashboardUrl must not be null]");
}
@Test
void post_validService_as_admin_200_ok(TestInfo test) throws IOException, URISyntaxException {
void post_validService_as_admin_200_ok(TestInfo test) throws IOException {
// Create dashboard service with different optional fields
Map<String, String> authHeaders = adminAuthHeaders();
createAndCheckEntity(create(test, 1).withDescription(null), authHeaders);
createAndCheckEntity(create(test, 2).withDescription("description"), authHeaders);
createAndCheckEntity(create(test, 3).withIngestionSchedule(null), authHeaders);
Map<String, String> authHeaders = ADMIN_AUTH_HEADERS;
createAndCheckEntity(createRequest(test, 1).withDescription(null), authHeaders);
createAndCheckEntity(createRequest(test, 2).withDescription("description"), authHeaders);
createAndCheckEntity(createRequest(test, 3).withIngestionSchedule(null), authHeaders);
}
@Test
void post_validService_as_non_admin_401(TestInfo test) {
// Create dashboard service with different optional fields
Map<String, String> authHeaders = authHeaders("test@open-metadata.org");
HttpResponseException exception =
assertThrows(
HttpResponseException.class,
() -> createAndCheckEntity(create(test, 1).withDescription(null), authHeaders));
() -> createAndCheckEntity(createRequest(test, 1).withDescription(null), TEST_AUTH_HEADERS));
TestUtils.assertResponse(exception, FORBIDDEN, "Principal: CatalogPrincipal{name='test'} is not admin");
}
@Test
void post_invalidIngestionSchedule_4xx(TestInfo test) throws URISyntaxException {
void post_invalidIngestionSchedule_4xx(TestInfo test) {
// No jdbc connection set
CreateDashboardService create = create(test);
Schedule schedule = create.getIngestionSchedule();
Schedule schedule = new Schedule().withStartDate(new Date()).withRepeatFrequency("P1D");
CreateDashboardService create = createRequest(test).withIngestionSchedule(schedule);
// Invalid format
create.withIngestionSchedule(schedule.withRepeatFrequency("INVALID"));
HttpResponseException exception =
assertThrows(HttpResponseException.class, () -> createEntity(create, adminAuthHeaders()));
assertThrows(HttpResponseException.class, () -> createEntity(create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponse(exception, BAD_REQUEST, "Invalid ingestion repeatFrequency INVALID");
// Duration that contains years, months and seconds are not allowed
create.withIngestionSchedule(schedule.withRepeatFrequency("P1Y"));
exception = assertThrows(HttpResponseException.class, () -> createEntity(create, adminAuthHeaders()));
exception = assertThrows(HttpResponseException.class, () -> createEntity(create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponse(
exception,
BAD_REQUEST,
"Ingestion repeatFrequency can only contain Days, Hours, " + "and Minutes - example P{d}DT{h}H{m}M");
create.withIngestionSchedule(schedule.withRepeatFrequency("P1M"));
exception = assertThrows(HttpResponseException.class, () -> createEntity(create, adminAuthHeaders()));
exception = assertThrows(HttpResponseException.class, () -> createEntity(create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponse(
exception,
BAD_REQUEST,
"Ingestion repeatFrequency can only contain Days, Hours, " + "and Minutes - example P{d}DT{h}H{m}M");
create.withIngestionSchedule(schedule.withRepeatFrequency("PT1S"));
exception = assertThrows(HttpResponseException.class, () -> createEntity(create, adminAuthHeaders()));
exception = assertThrows(HttpResponseException.class, () -> createEntity(create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponse(
exception,
BAD_REQUEST,
@ -134,31 +134,31 @@ public class DashboardServiceResourceTest extends EntityResourceTest<DashboardSe
}
@Test
void post_validIngestionSchedules_as_admin_200(TestInfo test) throws IOException, URISyntaxException {
void post_validIngestionSchedules_as_admin_200(TestInfo test) throws IOException {
Schedule schedule = new Schedule().withStartDate(new Date());
schedule.withRepeatFrequency("PT60M"); // Repeat every 60M should be valid
createAndCheckEntity(create(test, 1).withIngestionSchedule(schedule), adminAuthHeaders());
createAndCheckEntity(createRequest(test, 1).withIngestionSchedule(schedule), ADMIN_AUTH_HEADERS);
schedule.withRepeatFrequency("PT1H49M");
createAndCheckEntity(create(test, 2).withIngestionSchedule(schedule), adminAuthHeaders());
createAndCheckEntity(createRequest(test, 2).withIngestionSchedule(schedule), ADMIN_AUTH_HEADERS);
schedule.withRepeatFrequency("P1DT1H49M");
createAndCheckEntity(create(test, 3).withIngestionSchedule(schedule), adminAuthHeaders());
createAndCheckEntity(createRequest(test, 3).withIngestionSchedule(schedule), ADMIN_AUTH_HEADERS);
}
@Test
void post_ingestionScheduleIsTooShort_4xx(TestInfo test) throws URISyntaxException {
void post_ingestionScheduleIsTooShort_4xx(TestInfo test) {
// No jdbc connection set
CreateDashboardService create = create(test);
Schedule schedule = create.getIngestionSchedule();
Schedule schedule = new Schedule().withStartDate(new Date()).withRepeatFrequency("P1D");
CreateDashboardService create = createRequest(test).withIngestionSchedule(schedule);
create.withIngestionSchedule(schedule.withRepeatFrequency("PT1M")); // Repeat every 0 seconds
HttpResponseException exception =
assertThrows(HttpResponseException.class, () -> createEntity(create, adminAuthHeaders()));
assertThrows(HttpResponseException.class, () -> createEntity(create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponseContains(
exception, BAD_REQUEST, "Ingestion repeatFrequency is too short and must be more than 60 minutes");
create.withIngestionSchedule(schedule.withRepeatFrequency("PT59M")); // Repeat every 50 minutes 59 seconds
exception = assertThrows(HttpResponseException.class, () -> createEntity(create, adminAuthHeaders()));
exception = assertThrows(HttpResponseException.class, () -> createEntity(create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponse(
exception, BAD_REQUEST, "Ingestion repeatFrequency is too short and must " + "be more than 60 minutes");
}
@ -166,12 +166,12 @@ public class DashboardServiceResourceTest extends EntityResourceTest<DashboardSe
@Test
void put_updateService_as_admin_2xx(TestInfo test) throws IOException, URISyntaxException {
DashboardService service =
createAndCheckEntity(create(test).withDescription(null).withIngestionSchedule(null), adminAuthHeaders());
createAndCheckEntity(createRequest(test).withDescription(null).withIngestionSchedule(null), ADMIN_AUTH_HEADERS);
// Update dashboard description and ingestion service that are null
Schedule schedule = new Schedule().withStartDate(new Date()).withRepeatFrequency("P1D");
CreateDashboardService update =
create(test)
createRequest(test)
.withDescription("description1")
.withDashboardUrl(new URI("http://localhost:8080"))
.withUsername("user")
@ -189,7 +189,7 @@ public class DashboardServiceResourceTest extends EntityResourceTest<DashboardSe
.withName("dashboardUrl")
.withOldValue("http://192.1.1.1:0")
.withNewValue("http://localhost:8080"));
service = updateAndCheckEntity(update, OK, adminAuthHeaders(), UpdateType.MINOR_UPDATE, change);
service = updateAndCheckEntity(update, OK, ADMIN_AUTH_HEADERS, UpdateType.MINOR_UPDATE, change);
// Update ingestion schedule
Schedule schedule1 = new Schedule().withStartDate(new Date()).withRepeatFrequency("PT1H");
@ -198,54 +198,42 @@ public class DashboardServiceResourceTest extends EntityResourceTest<DashboardSe
.getFieldsUpdated()
.add(new FieldChange().withName("ingestionSchedule").withOldValue(schedule).withNewValue(schedule1));
update.withIngestionSchedule(schedule1);
updateAndCheckEntity(update, OK, adminAuthHeaders(), UpdateType.MINOR_UPDATE, change);
updateAndCheckEntity(update, OK, ADMIN_AUTH_HEADERS, UpdateType.MINOR_UPDATE, change);
}
@Test
void put_update_as_non_admin_401(TestInfo test) throws IOException, URISyntaxException {
Map<String, String> authHeaders = adminAuthHeaders();
createAndCheckEntity(create(test).withDescription(null).withIngestionSchedule(null), authHeaders);
void put_update_as_non_admin_401(TestInfo test) throws IOException {
Map<String, String> authHeaders = ADMIN_AUTH_HEADERS;
createAndCheckEntity(createRequest(test).withDescription(null).withIngestionSchedule(null), authHeaders);
// Update dashboard description and ingestion service that are null
HttpResponseException exception =
assertThrows(
HttpResponseException.class,
() ->
updateAndCheckEntity(
create(test), OK, authHeaders("test@open-metadata.org"), UpdateType.NO_CHANGE, null));
() -> updateAndCheckEntity(createRequest(test), OK, TEST_AUTH_HEADERS, UpdateType.NO_CHANGE, null));
TestUtils.assertResponse(exception, FORBIDDEN, "Principal: CatalogPrincipal{name='test'} " + "is not admin");
}
private CreateDashboardService create(TestInfo test) throws URISyntaxException {
return create(getEntityName(test));
}
private CreateDashboardService create(TestInfo test, int index) throws URISyntaxException {
return create(getEntityName(test, index));
}
private CreateDashboardService create(String name) throws URISyntaxException {
return new CreateDashboardService()
.withName(name)
.withServiceType(CreateDashboardService.DashboardServiceType.Superset)
.withDashboardUrl(new URI("http://192.1.1.1:0"))
.withIngestionSchedule(new Schedule().withStartDate(new Date()).withRepeatFrequency("P1D"));
@Override
public CreateDashboardService createRequest(
String name, String description, String displayName, EntityReference owner) {
try {
return new CreateDashboardService()
.withName(name)
.withServiceType(CreateDashboardService.DashboardServiceType.Superset)
.withDashboardUrl(new URI("http://192.1.1.1:0"))
// .withIngestionSchedule(new Schedule().withStartDate(new Date()).withRepeatFrequency("P1D"))
.withIngestionSchedule(null)
.withDescription(description);
} catch (URISyntaxException e) {
e.printStackTrace();
}
return null;
}
@Override
public Object createRequest(String name, String description, String displayName, EntityReference owner)
throws URISyntaxException {
return create(name).withDescription(description).withIngestionSchedule(null);
}
@Override
public EntityReference getContainer(Object createRequest) throws URISyntaxException {
return null; // No container entity
}
@Override
public void validateCreatedEntity(DashboardService service, Object request, Map<String, String> authHeaders) {
CreateDashboardService createRequest = (CreateDashboardService) request;
public void validateCreatedEntity(
DashboardService service, CreateDashboardService createRequest, Map<String, String> authHeaders) {
validateCommonEntityFields(
getEntityInterface(service), createRequest.getDescription(), getPrincipal(authHeaders), null);
assertEquals(createRequest.getName(), service.getName());
@ -258,7 +246,8 @@ public class DashboardServiceResourceTest extends EntityResourceTest<DashboardSe
}
@Override
public void validateUpdatedEntity(DashboardService service, Object request, Map<String, String> authHeaders) {
public void validateUpdatedEntity(
DashboardService service, CreateDashboardService request, Map<String, String> authHeaders) {
validateCreatedEntity(service, request, authHeaders);
}
@ -278,8 +267,8 @@ public class DashboardServiceResourceTest extends EntityResourceTest<DashboardSe
String fields = "";
service =
byName
? getEntityByName(service.getName(), null, fields, adminAuthHeaders())
: getEntity(service.getId(), fields, adminAuthHeaders());
? getEntityByName(service.getName(), fields, ADMIN_AUTH_HEADERS)
: getEntity(service.getId(), fields, ADMIN_AUTH_HEADERS);
TestUtils.assertListNotNull(
service.getHref(),
service.getVersion(),

View File

@ -19,12 +19,11 @@ import static javax.ws.rs.core.Response.Status.OK;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.openmetadata.catalog.Entity.helper;
import static org.openmetadata.catalog.security.SecurityUtil.authHeaders;
import static org.openmetadata.catalog.util.TestUtils.adminAuthHeaders;
import static org.openmetadata.catalog.util.TestUtils.ADMIN_AUTH_HEADERS;
import static org.openmetadata.catalog.util.TestUtils.TEST_AUTH_HEADERS;
import static org.openmetadata.catalog.util.TestUtils.getPrincipal;
import java.io.IOException;
import java.net.URISyntaxException;
import java.text.ParseException;
import java.util.Arrays;
import java.util.Map;
@ -58,7 +57,7 @@ import org.openmetadata.catalog.util.TestUtils;
import org.openmetadata.catalog.util.TestUtils.UpdateType;
@Slf4j
public class DatabaseServiceResourceTest extends EntityResourceTest<DatabaseService> {
public class DatabaseServiceResourceTest extends EntityResourceTest<DatabaseService, CreateDatabaseService> {
public DatabaseServiceResourceTest() {
super(
Entity.DATABASE_SERVICE,
@ -76,42 +75,40 @@ public class DatabaseServiceResourceTest extends EntityResourceTest<DatabaseServ
@Test
void post_validDatabaseService_as_admin_200_ok(TestInfo test) throws IOException {
// Create database service with different optional fields
Map<String, String> authHeaders = adminAuthHeaders();
createAndCheckEntity(create(test, 1).withDescription(null), authHeaders);
createAndCheckEntity(create(test, 2).withDescription("description"), authHeaders);
Map<String, String> authHeaders = ADMIN_AUTH_HEADERS;
createAndCheckEntity(createRequest(test, 1).withDescription(null), authHeaders);
createAndCheckEntity(createRequest(test, 2).withDescription("description"), authHeaders);
}
@Test
void post_validDatabaseService_as_non_admin_401(TestInfo test) {
// Create database service with different optional fields
Map<String, String> authHeaders = authHeaders("test@open-metadata.org");
HttpResponseException exception =
assertThrows(
HttpResponseException.class,
() -> createAndCheckEntity(create(test, 1).withDescription(null), authHeaders));
() -> createAndCheckEntity(createRequest(test, 1).withDescription(null), TEST_AUTH_HEADERS));
TestUtils.assertResponse(exception, FORBIDDEN, "Principal: CatalogPrincipal{name='test'} is not admin");
}
@Test
void post_invalidDatabaseServiceNoJdbc_4xx(TestInfo test) {
// No jdbc connection set
CreateDatabaseService create = create(test).withDatabaseConnection(null);
CreateDatabaseService create = createRequest(test).withDatabaseConnection(null);
HttpResponseException exception =
assertThrows(HttpResponseException.class, () -> createEntity(create, adminAuthHeaders()));
assertThrows(HttpResponseException.class, () -> createEntity(create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponseContains(exception, BAD_REQUEST, "databaseConnection must not be null");
}
@Test
void put_updateDatabaseService_as_admin_2xx(TestInfo test) throws IOException {
DatabaseService service = createAndCheckEntity(create(test).withDescription(null), adminAuthHeaders());
DatabaseService service = createAndCheckEntity(createRequest(test).withDescription(null), ADMIN_AUTH_HEADERS);
// Update database description and ingestion service that are null
CreateDatabaseService update = create(test).withDescription("description1");
CreateDatabaseService update = createRequest(test).withDescription("description1");
ChangeDescription change = getChangeDescription(service.getVersion());
change.getFieldsAdded().add(new FieldChange().withName("description").withNewValue("description1"));
updateAndCheckEntity(update, OK, adminAuthHeaders(), UpdateType.MINOR_UPDATE, change);
updateAndCheckEntity(update, OK, ADMIN_AUTH_HEADERS, UpdateType.MINOR_UPDATE, change);
DatabaseConnection databaseConnection =
new DatabaseConnection()
.withDatabase("test")
@ -119,7 +116,7 @@ public class DatabaseServiceResourceTest extends EntityResourceTest<DatabaseServ
.withPassword("password")
.withUsername("username");
update.withDatabaseConnection(databaseConnection);
service = updateEntity(update, OK, adminAuthHeaders());
service = updateEntity(update, OK, ADMIN_AUTH_HEADERS);
assertEquals(databaseConnection, service.getDatabaseConnection());
ConnectionArguments connectionArguments =
new ConnectionArguments()
@ -129,20 +126,20 @@ public class DatabaseServiceResourceTest extends EntityResourceTest<DatabaseServ
new ConnectionOptions().withAdditionalProperty("key1", "value1").withAdditionalProperty("key2", "value2");
databaseConnection.withConnectionArguments(connectionArguments).withConnectionOptions(connectionOptions);
update.withDatabaseConnection(databaseConnection);
service = updateEntity(update, OK, adminAuthHeaders());
service = updateEntity(update, OK, ADMIN_AUTH_HEADERS);
assertEquals(databaseConnection, service.getDatabaseConnection());
}
@Test
void put_addIngestion_as_admin_2xx(TestInfo test) throws IOException, ParseException {
DatabaseService service = createAndCheckEntity(create(test).withDescription(null), adminAuthHeaders());
DatabaseService service = createAndCheckEntity(createRequest(test).withDescription(null), ADMIN_AUTH_HEADERS);
// Update database description and ingestion service that are null
CreateDatabaseService update = create(test).withDescription("description1");
CreateDatabaseService update = createRequest(test).withDescription("description1");
ChangeDescription change = getChangeDescription(service.getVersion());
change.getFieldsAdded().add(new FieldChange().withName("description").withNewValue("description1"));
updateAndCheckEntity(update, OK, adminAuthHeaders(), UpdateType.MINOR_UPDATE, change);
updateAndCheckEntity(update, OK, ADMIN_AUTH_HEADERS, UpdateType.MINOR_UPDATE, change);
DatabaseConnection databaseConnection =
new DatabaseConnection()
.withDatabase("test")
@ -150,7 +147,7 @@ public class DatabaseServiceResourceTest extends EntityResourceTest<DatabaseServ
.withPassword("password")
.withUsername("username");
update.withDatabaseConnection(databaseConnection);
service = updateEntity(update, OK, adminAuthHeaders());
service = updateEntity(update, OK, ADMIN_AUTH_HEADERS);
assertEquals(databaseConnection, service.getDatabaseConnection());
ConnectionArguments connectionArguments =
new ConnectionArguments()
@ -160,12 +157,12 @@ public class DatabaseServiceResourceTest extends EntityResourceTest<DatabaseServ
new ConnectionOptions().withAdditionalProperty("key1", "value1").withAdditionalProperty("key2", "value2");
databaseConnection.withConnectionArguments(connectionArguments).withConnectionOptions(connectionOptions);
update.withDatabaseConnection(databaseConnection);
service = updateEntity(update, OK, adminAuthHeaders());
service = updateEntity(update, OK, ADMIN_AUTH_HEADERS);
assertEquals(databaseConnection, service.getDatabaseConnection());
AirflowPipelineResourceTest airflowPipelineResourceTest = new AirflowPipelineResourceTest();
CreateAirflowPipeline createAirflowPipeline =
airflowPipelineResourceTest.create(test).withService(helper(service).toEntityReference());
airflowPipelineResourceTest.createRequest(test).withService(helper(service).toEntityReference());
DatabaseServiceMetadataPipeline databaseServiceMetadataPipeline =
new DatabaseServiceMetadataPipeline()
@ -179,8 +176,8 @@ public class DatabaseServiceResourceTest extends EntityResourceTest<DatabaseServ
.withConfig(databaseServiceMetadataPipeline);
createAirflowPipeline.withPipelineConfig(pipelineConfig);
AirflowPipeline airflowPipeline =
airflowPipelineResourceTest.createEntity(createAirflowPipeline, adminAuthHeaders());
DatabaseService updatedService = getEntity(service.getId(), "airflowPipeline", adminAuthHeaders());
airflowPipelineResourceTest.createEntity(createAirflowPipeline, ADMIN_AUTH_HEADERS);
DatabaseService updatedService = getEntity(service.getId(), "airflowPipeline", ADMIN_AUTH_HEADERS);
assertEquals(1, updatedService.getAirflowPipelines().size());
EntityReference expectedPipeline = updatedService.getAirflowPipelines().get(0);
assertEquals(airflowPipeline.getId(), expectedPipeline.getId());
@ -189,47 +186,30 @@ public class DatabaseServiceResourceTest extends EntityResourceTest<DatabaseServ
@Test
void put_update_as_non_admin_401(TestInfo test) throws IOException {
Map<String, String> authHeaders = adminAuthHeaders();
createAndCheckEntity(create(test).withDescription(null), authHeaders);
Map<String, String> authHeaders = ADMIN_AUTH_HEADERS;
createAndCheckEntity(createRequest(test).withDescription(null), authHeaders);
// Update as non admin should be forbidden
HttpResponseException exception =
assertThrows(
HttpResponseException.class,
() ->
updateAndCheckEntity(
create(test), OK, authHeaders("test@open-metadata.org"), UpdateType.MINOR_UPDATE, null));
() -> updateAndCheckEntity(createRequest(test), OK, TEST_AUTH_HEADERS, UpdateType.MINOR_UPDATE, null));
TestUtils.assertResponse(exception, FORBIDDEN, "Principal: CatalogPrincipal{name='test'} " + "is not admin");
}
public CreateDatabaseService create(TestInfo test) {
return create(getEntityName(test));
}
private CreateDatabaseService create(TestInfo test, int index) {
return create(getEntityName(test, index));
}
private CreateDatabaseService create(String name) {
@Override
public CreateDatabaseService createRequest(
String name, String description, String displayName, EntityReference owner) {
return new CreateDatabaseService()
.withName(name)
.withServiceType(DatabaseServiceType.Snowflake)
.withDatabaseConnection(TestUtils.DATABASE_CONNECTION);
.withDatabaseConnection(TestUtils.DATABASE_CONNECTION)
.withDescription(description);
}
@Override
public Object createRequest(String name, String description, String displayName, EntityReference owner) {
return create(name).withDescription(description);
}
@Override
public EntityReference getContainer(Object createRequest) throws URISyntaxException {
return null; // No container entity
}
@Override
public void validateCreatedEntity(DatabaseService service, Object request, Map<String, String> authHeaders) {
CreateDatabaseService createRequest = (CreateDatabaseService) request;
public void validateCreatedEntity(
DatabaseService service, CreateDatabaseService createRequest, Map<String, String> authHeaders) {
validateCommonEntityFields(
getEntityInterface(service), createRequest.getDescription(), getPrincipal(authHeaders), null);
assertEquals(createRequest.getName(), service.getName());
@ -239,7 +219,8 @@ public class DatabaseServiceResourceTest extends EntityResourceTest<DatabaseServ
}
@Override
public void validateUpdatedEntity(DatabaseService service, Object request, Map<String, String> authHeaders) {
public void validateUpdatedEntity(
DatabaseService service, CreateDatabaseService request, Map<String, String> authHeaders) {
validateCreatedEntity(service, request, authHeaders);
}
@ -259,8 +240,8 @@ public class DatabaseServiceResourceTest extends EntityResourceTest<DatabaseServ
String fields = "";
service =
byName
? getEntityByName(service.getName(), null, fields, adminAuthHeaders())
: getEntity(service.getId(), fields, adminAuthHeaders());
? getEntityByName(service.getName(), fields, ADMIN_AUTH_HEADERS)
: getEntity(service.getId(), fields, ADMIN_AUTH_HEADERS);
TestUtils.assertListNotNull(
service.getHref(),
service.getVersion(),

View File

@ -19,8 +19,8 @@ import static javax.ws.rs.core.Response.Status.OK;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.openmetadata.catalog.security.SecurityUtil.authHeaders;
import static org.openmetadata.catalog.util.TestUtils.adminAuthHeaders;
import static org.openmetadata.catalog.util.TestUtils.ADMIN_AUTH_HEADERS;
import static org.openmetadata.catalog.util.TestUtils.TEST_AUTH_HEADERS;
import java.io.IOException;
import java.net.URI;
@ -50,7 +50,7 @@ import org.openmetadata.catalog.util.TestUtils;
import org.openmetadata.catalog.util.TestUtils.UpdateType;
@Slf4j
public class MessagingServiceResourceTest extends EntityResourceTest<MessagingService> {
public class MessagingServiceResourceTest extends EntityResourceTest<MessagingService, CreateMessagingService> {
public static List<String> KAFKA_BROKERS;
public static URI SCHEMA_REGISTRY_URL;
@ -80,66 +80,65 @@ public class MessagingServiceResourceTest extends EntityResourceTest<MessagingSe
// Create messaging with mandatory serviceType field empty
HttpResponseException exception =
assertThrows(
HttpResponseException.class, () -> createEntity(create(test).withServiceType(null), adminAuthHeaders()));
HttpResponseException.class,
() -> createEntity(createRequest(test).withServiceType(null), ADMIN_AUTH_HEADERS));
TestUtils.assertResponse(exception, BAD_REQUEST, "[serviceType must not be null]");
// Create messaging with mandatory brokers field empty
exception =
assertThrows(
HttpResponseException.class, () -> createEntity(create(test).withBrokers(null), adminAuthHeaders()));
HttpResponseException.class, () -> createEntity(createRequest(test).withBrokers(null), ADMIN_AUTH_HEADERS));
TestUtils.assertResponse(exception, BAD_REQUEST, "[brokers must not be null]");
}
@Test
void post_validService_as_admin_200_ok(TestInfo test) throws IOException {
// Create messaging service with different optional fields
Map<String, String> authHeaders = adminAuthHeaders();
createAndCheckEntity(create(test, 1).withDescription(null), authHeaders);
createAndCheckEntity(create(test, 2).withDescription("description"), authHeaders);
createAndCheckEntity(create(test, 3).withIngestionSchedule(null), authHeaders);
Map<String, String> authHeaders = ADMIN_AUTH_HEADERS;
createAndCheckEntity(createRequest(test, 1).withDescription(null), authHeaders);
createAndCheckEntity(createRequest(test, 2).withDescription("description"), authHeaders);
createAndCheckEntity(createRequest(test, 3).withIngestionSchedule(null), authHeaders);
}
@Test
void post_validService_as_non_admin_401(TestInfo test) {
// Create messaging service with different optional fields
Map<String, String> authHeaders = authHeaders("test@open-metadata.org");
HttpResponseException exception =
assertThrows(
HttpResponseException.class,
() -> createAndCheckEntity(create(test, 1).withDescription(null), authHeaders));
() -> createAndCheckEntity(createRequest(test, 1).withDescription(null), TEST_AUTH_HEADERS));
TestUtils.assertResponse(exception, FORBIDDEN, "Principal: CatalogPrincipal{name='test'} is not admin");
}
@Test
void post_invalidIngestionSchedule_4xx(TestInfo test) {
// No jdbc connection set
CreateMessagingService create = create(test);
Schedule schedule = create.getIngestionSchedule();
Schedule schedule = new Schedule().withStartDate(new Date()).withRepeatFrequency("P1D");
CreateMessagingService create = createRequest(test).withIngestionSchedule(schedule);
// Invalid format
create.withIngestionSchedule(schedule.withRepeatFrequency("INVALID"));
HttpResponseException exception =
assertThrows(HttpResponseException.class, () -> createEntity(create, adminAuthHeaders()));
assertThrows(HttpResponseException.class, () -> createEntity(create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponse(exception, BAD_REQUEST, "Invalid ingestion repeatFrequency INVALID");
// Duration that contains years, months and seconds are not allowed
create.withIngestionSchedule(schedule.withRepeatFrequency("P1Y"));
exception = assertThrows(HttpResponseException.class, () -> createEntity(create, adminAuthHeaders()));
exception = assertThrows(HttpResponseException.class, () -> createEntity(create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponse(
exception,
BAD_REQUEST,
"Ingestion repeatFrequency can only contain Days, Hours, " + "and Minutes - example P{d}DT{h}H{m}M");
create.withIngestionSchedule(schedule.withRepeatFrequency("P1M"));
exception = assertThrows(HttpResponseException.class, () -> createEntity(create, adminAuthHeaders()));
exception = assertThrows(HttpResponseException.class, () -> createEntity(create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponse(
exception,
BAD_REQUEST,
"Ingestion repeatFrequency can only contain Days, Hours, " + "and Minutes - example P{d}DT{h}H{m}M");
create.withIngestionSchedule(schedule.withRepeatFrequency("PT1S"));
exception = assertThrows(HttpResponseException.class, () -> createEntity(create, adminAuthHeaders()));
exception = assertThrows(HttpResponseException.class, () -> createEntity(create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponse(
exception,
BAD_REQUEST,
@ -150,28 +149,28 @@ public class MessagingServiceResourceTest extends EntityResourceTest<MessagingSe
void post_validIngestionSchedules_as_admin_200(TestInfo test) throws IOException {
Schedule schedule = new Schedule().withStartDate(new Date());
schedule.withRepeatFrequency("PT60M"); // Repeat every 60M should be valid
createAndCheckEntity(create(test, 1).withIngestionSchedule(schedule), adminAuthHeaders());
createAndCheckEntity(createRequest(test, 1).withIngestionSchedule(schedule), ADMIN_AUTH_HEADERS);
schedule.withRepeatFrequency("PT1H49M");
createAndCheckEntity(create(test, 2).withIngestionSchedule(schedule), adminAuthHeaders());
createAndCheckEntity(createRequest(test, 2).withIngestionSchedule(schedule), ADMIN_AUTH_HEADERS);
schedule.withRepeatFrequency("P1DT1H49M");
createAndCheckEntity(create(test, 3).withIngestionSchedule(schedule), adminAuthHeaders());
createAndCheckEntity(createRequest(test, 3).withIngestionSchedule(schedule), ADMIN_AUTH_HEADERS);
}
@Test
void post_ingestionScheduleIsTooShort_4xx(TestInfo test) {
// No jdbc connection set
CreateMessagingService create = create(test);
Schedule schedule = create.getIngestionSchedule();
Schedule schedule = new Schedule().withStartDate(new Date()).withRepeatFrequency("P1D");
CreateMessagingService create = createRequest(test).withIngestionSchedule(schedule);
create.withIngestionSchedule(schedule.withRepeatFrequency("PT1M")); // Repeat every 0 seconds
HttpResponseException exception =
assertThrows(HttpResponseException.class, () -> createEntity(create, adminAuthHeaders()));
assertThrows(HttpResponseException.class, () -> createEntity(create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponseContains(
exception, BAD_REQUEST, "Ingestion repeatFrequency is too short and must be more than 60 minutes");
create.withIngestionSchedule(schedule.withRepeatFrequency("PT59M")); // Repeat every 50 minutes 59 seconds
exception = assertThrows(HttpResponseException.class, () -> createEntity(create, adminAuthHeaders()));
exception = assertThrows(HttpResponseException.class, () -> createEntity(create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponse(
exception, BAD_REQUEST, "Ingestion repeatFrequency is too short and must " + "be more than 60 minutes");
}
@ -180,25 +179,25 @@ public class MessagingServiceResourceTest extends EntityResourceTest<MessagingSe
void put_updateService_as_admin_2xx(TestInfo test) throws IOException, URISyntaxException {
MessagingService service =
createAndCheckEntity(
create(test)
createRequest(test)
.withDescription(null)
.withIngestionSchedule(null)
.withBrokers(KAFKA_BROKERS)
.withSchemaRegistry(SCHEMA_REGISTRY_URL),
adminAuthHeaders());
ADMIN_AUTH_HEADERS);
// Update messaging description and ingestion service that are null
CreateMessagingService update = create(test).withDescription("description1").withIngestionSchedule(null);
CreateMessagingService update = createRequest(test).withDescription("description1").withIngestionSchedule(null);
ChangeDescription change = getChangeDescription(service.getVersion());
change.getFieldsAdded().add(new FieldChange().withName("description").withNewValue("description1"));
service = updateAndCheckEntity(update, OK, adminAuthHeaders(), UpdateType.MINOR_UPDATE, change);
service = updateAndCheckEntity(update, OK, ADMIN_AUTH_HEADERS, UpdateType.MINOR_UPDATE, change);
// Update ingestion schedule
Schedule schedule = new Schedule().withStartDate(new Date()).withRepeatFrequency("P1D");
change = getChangeDescription(service.getVersion());
change.getFieldsAdded().add(new FieldChange().withName("ingestionSchedule").withNewValue(schedule));
update.withIngestionSchedule(schedule);
service = updateAndCheckEntity(update, OK, adminAuthHeaders(), UpdateType.MINOR_UPDATE, change);
service = updateAndCheckEntity(update, OK, ADMIN_AUTH_HEADERS, UpdateType.MINOR_UPDATE, change);
// Update description and ingestion schedule again
Schedule schedule1 = new Schedule().withStartDate(new Date()).withRepeatFrequency("PT1H");
@ -207,7 +206,7 @@ public class MessagingServiceResourceTest extends EntityResourceTest<MessagingSe
change
.getFieldsUpdated()
.add(new FieldChange().withName("ingestionSchedule").withOldValue(schedule).withNewValue(schedule1));
service = updateAndCheckEntity(update, OK, adminAuthHeaders(), UpdateType.MINOR_UPDATE, change);
service = updateAndCheckEntity(update, OK, ADMIN_AUTH_HEADERS, UpdateType.MINOR_UPDATE, change);
// update broker list and schema registry
List<String> updatedBrokers = List.of("localhost:0");
@ -225,54 +224,37 @@ public class MessagingServiceResourceTest extends EntityResourceTest<MessagingSe
.withOldValue(SCHEMA_REGISTRY_URL)
.withNewValue(updatedSchemaRegistry));
updateAndCheckEntity(update, OK, adminAuthHeaders(), UpdateType.MINOR_UPDATE, change);
updateAndCheckEntity(update, OK, ADMIN_AUTH_HEADERS, UpdateType.MINOR_UPDATE, change);
}
@Test
void put_update_as_non_admin_401(TestInfo test) throws IOException {
Map<String, String> authHeaders = adminAuthHeaders();
createAndCheckEntity(create(test).withDescription(null).withIngestionSchedule(null), authHeaders);
createAndCheckEntity(createRequest(test).withDescription(null).withIngestionSchedule(null), ADMIN_AUTH_HEADERS);
// Update messaging description as non admin and expect exception
HttpResponseException exception =
assertThrows(
HttpResponseException.class,
() ->
updateAndCheckEntity(
create(test), OK, authHeaders("test@open-metadata.org"), UpdateType.NO_CHANGE, null));
() -> updateAndCheckEntity(createRequest(test), OK, TEST_AUTH_HEADERS, UpdateType.NO_CHANGE, null));
TestUtils.assertResponse(exception, FORBIDDEN, "Principal: CatalogPrincipal{name='test'} " + "is not admin");
}
private CreateMessagingService create(TestInfo test) {
return create(getEntityName(test));
}
private CreateMessagingService create(TestInfo test, int index) {
return create(getEntityName(test, index));
}
private CreateMessagingService create(String name) {
@Override
public CreateMessagingService createRequest(
String name, String description, String displayName, EntityReference owner) {
return new CreateMessagingService()
.withName(name)
.withServiceType(MessagingServiceType.Kafka)
.withBrokers(KAFKA_BROKERS)
.withSchemaRegistry(SCHEMA_REGISTRY_URL)
.withIngestionSchedule(new Schedule().withStartDate(new Date()).withRepeatFrequency("P1D"));
// .withIngestionSchedule(new Schedule().withStartDate(new Date()).withRepeatFrequency("P1D"));
.withDescription(description)
.withIngestionSchedule(null);
}
@Override
public Object createRequest(String name, String description, String displayName, EntityReference owner) {
return create(name).withDescription(description).withIngestionSchedule(null);
}
@Override
public EntityReference getContainer(Object createRequest) throws URISyntaxException {
return null; //// No container entity
}
@Override
public void validateCreatedEntity(MessagingService service, Object request, Map<String, String> authHeaders) {
CreateMessagingService createRequest = (CreateMessagingService) request;
public void validateCreatedEntity(
MessagingService service, CreateMessagingService createRequest, Map<String, String> authHeaders) {
validateCommonEntityFields(
getEntityInterface(service), createRequest.getDescription(), TestUtils.getPrincipal(authHeaders), null);
Schedule expectedIngestion = createRequest.getIngestionSchedule();
@ -285,7 +267,8 @@ public class MessagingServiceResourceTest extends EntityResourceTest<MessagingSe
}
@Override
public void validateUpdatedEntity(MessagingService service, Object request, Map<String, String> authHeaders) {
public void validateUpdatedEntity(
MessagingService service, CreateMessagingService request, Map<String, String> authHeaders) {
validateCreatedEntity(service, request, authHeaders);
}
@ -305,8 +288,8 @@ public class MessagingServiceResourceTest extends EntityResourceTest<MessagingSe
String fields = "";
service =
byName
? getEntityByName(service.getName(), null, fields, adminAuthHeaders())
: getEntity(service.getId(), fields, adminAuthHeaders());
? getEntityByName(service.getName(), fields, ADMIN_AUTH_HEADERS)
: getEntity(service.getId(), fields, ADMIN_AUTH_HEADERS);
TestUtils.assertListNotNull(
service.getHref(),
service.getVersion(),

View File

@ -18,8 +18,8 @@ import static javax.ws.rs.core.Response.Status.FORBIDDEN;
import static javax.ws.rs.core.Response.Status.OK;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.openmetadata.catalog.security.SecurityUtil.authHeaders;
import static org.openmetadata.catalog.util.TestUtils.adminAuthHeaders;
import static org.openmetadata.catalog.util.TestUtils.ADMIN_AUTH_HEADERS;
import static org.openmetadata.catalog.util.TestUtils.TEST_AUTH_HEADERS;
import static org.openmetadata.catalog.util.TestUtils.getPrincipal;
import java.io.IOException;
@ -48,7 +48,7 @@ import org.openmetadata.catalog.util.TestUtils;
import org.openmetadata.catalog.util.TestUtils.UpdateType;
@Slf4j
public class PipelineServiceResourceTest extends EntityResourceTest<PipelineService> {
public class PipelineServiceResourceTest extends EntityResourceTest<PipelineService, CreatePipelineService> {
public static URI PIPELINE_SERVICE_URL;
@ -78,66 +78,66 @@ public class PipelineServiceResourceTest extends EntityResourceTest<PipelineServ
// Create pipeline with mandatory serviceType field empty
HttpResponseException exception =
assertThrows(
HttpResponseException.class, () -> createEntity(create(test).withServiceType(null), adminAuthHeaders()));
HttpResponseException.class,
() -> createEntity(createRequest(test).withServiceType(null), ADMIN_AUTH_HEADERS));
TestUtils.assertResponse(exception, BAD_REQUEST, "[serviceType must not be null]");
// Create pipeline with mandatory `brokers` field empty
exception =
assertThrows(
HttpResponseException.class, () -> createEntity(create(test).withPipelineUrl(null), adminAuthHeaders()));
HttpResponseException.class,
() -> createEntity(createRequest(test).withPipelineUrl(null), ADMIN_AUTH_HEADERS));
TestUtils.assertResponse(exception, BAD_REQUEST, "[pipelineUrl must not be null]");
}
@Test
void post_validService_as_admin_200_ok(TestInfo test) throws IOException {
// Create pipeline service with different optional fields
Map<String, String> authHeaders = adminAuthHeaders();
createAndCheckEntity(create(test, 1).withDescription(null), authHeaders);
createAndCheckEntity(create(test, 2).withDescription("description"), authHeaders);
createAndCheckEntity(create(test, 3).withIngestionSchedule(null), authHeaders);
Map<String, String> authHeaders = ADMIN_AUTH_HEADERS;
createAndCheckEntity(createRequest(test, 1).withDescription(null), authHeaders);
createAndCheckEntity(createRequest(test, 2).withDescription("description"), authHeaders);
createAndCheckEntity(createRequest(test, 3).withIngestionSchedule(null), authHeaders);
}
@Test
void post_validService_as_non_admin_401(TestInfo test) {
// Create pipeline service with different optional fields
Map<String, String> authHeaders = authHeaders("test@open-metadata.org");
HttpResponseException exception =
assertThrows(
HttpResponseException.class,
() -> createAndCheckEntity(create(test, 1).withDescription(null), authHeaders));
() -> createAndCheckEntity(createRequest(test, 1).withDescription(null), TEST_AUTH_HEADERS));
TestUtils.assertResponse(exception, FORBIDDEN, "Principal: CatalogPrincipal{name='test'} is not admin");
}
@Test
void post_invalidIngestionSchedule_4xx(TestInfo test) {
// No jdbc connection set
CreatePipelineService create = create(test);
Schedule schedule = create.getIngestionSchedule();
Schedule schedule = new Schedule().withStartDate(new Date()).withRepeatFrequency("P1D");
CreatePipelineService create = createRequest(test).withIngestionSchedule(schedule);
// Invalid format
create.withIngestionSchedule(schedule.withRepeatFrequency("INVALID"));
HttpResponseException exception =
assertThrows(HttpResponseException.class, () -> createEntity(create, adminAuthHeaders()));
assertThrows(HttpResponseException.class, () -> createEntity(create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponse(exception, BAD_REQUEST, "Invalid ingestion repeatFrequency INVALID");
// Duration that contains years, months and seconds are not allowed
create.withIngestionSchedule(schedule.withRepeatFrequency("P1Y"));
exception = assertThrows(HttpResponseException.class, () -> createEntity(create, adminAuthHeaders()));
exception = assertThrows(HttpResponseException.class, () -> createEntity(create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponse(
exception,
BAD_REQUEST,
"Ingestion repeatFrequency can only contain Days, Hours, " + "and Minutes - example P{d}DT{h}H{m}M");
create.withIngestionSchedule(schedule.withRepeatFrequency("P1M"));
exception = assertThrows(HttpResponseException.class, () -> createEntity(create, adminAuthHeaders()));
exception = assertThrows(HttpResponseException.class, () -> createEntity(create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponse(
exception,
BAD_REQUEST,
"Ingestion repeatFrequency can only contain Days, Hours, " + "and Minutes - example P{d}DT{h}H{m}M");
create.withIngestionSchedule(schedule.withRepeatFrequency("PT1S"));
exception = assertThrows(HttpResponseException.class, () -> createEntity(create, adminAuthHeaders()));
exception = assertThrows(HttpResponseException.class, () -> createEntity(create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponse(
exception,
BAD_REQUEST,
@ -148,28 +148,28 @@ public class PipelineServiceResourceTest extends EntityResourceTest<PipelineServ
void post_validIngestionSchedules_as_admin_200(TestInfo test) throws IOException {
Schedule schedule = new Schedule().withStartDate(new Date());
schedule.withRepeatFrequency("PT60M"); // Repeat every 60M should be valid
createAndCheckEntity(create(test, 1).withIngestionSchedule(schedule), adminAuthHeaders());
createAndCheckEntity(createRequest(test, 1).withIngestionSchedule(schedule), ADMIN_AUTH_HEADERS);
schedule.withRepeatFrequency("PT1H49M");
createAndCheckEntity(create(test, 2).withIngestionSchedule(schedule), adminAuthHeaders());
createAndCheckEntity(createRequest(test, 2).withIngestionSchedule(schedule), ADMIN_AUTH_HEADERS);
schedule.withRepeatFrequency("P1DT1H49M");
createAndCheckEntity(create(test, 3).withIngestionSchedule(schedule), adminAuthHeaders());
createAndCheckEntity(createRequest(test, 3).withIngestionSchedule(schedule), ADMIN_AUTH_HEADERS);
}
@Test
void post_ingestionScheduleIsTooShort_4xx(TestInfo test) {
// No jdbc connection set
CreatePipelineService create = create(test);
Schedule schedule = create.getIngestionSchedule();
Schedule schedule = new Schedule().withStartDate(new Date()).withRepeatFrequency("P1D");
CreatePipelineService create = createRequest(test).withIngestionSchedule(schedule);
create.withIngestionSchedule(schedule.withRepeatFrequency("PT1M")); // Repeat every 0 seconds
HttpResponseException exception =
assertThrows(HttpResponseException.class, () -> createEntity(create, adminAuthHeaders()));
assertThrows(HttpResponseException.class, () -> createEntity(create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponseContains(
exception, BAD_REQUEST, "Ingestion repeatFrequency is too short and must be more than 60 minutes");
create.withIngestionSchedule(schedule.withRepeatFrequency("PT59M")); // Repeat every 50 minutes 59 seconds
exception = assertThrows(HttpResponseException.class, () -> createEntity(create, adminAuthHeaders()));
exception = assertThrows(HttpResponseException.class, () -> createEntity(create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponse(
exception, BAD_REQUEST, "Ingestion repeatFrequency is too short and must " + "be more than 60 minutes");
}
@ -178,16 +178,15 @@ public class PipelineServiceResourceTest extends EntityResourceTest<PipelineServ
void put_updateService_as_admin_2xx(TestInfo test) throws IOException, URISyntaxException {
PipelineService service =
createAndCheckEntity(
create(test).withDescription(null).withIngestionSchedule(null).withPipelineUrl(PIPELINE_SERVICE_URL),
adminAuthHeaders());
createRequest(test).withDescription(null).withPipelineUrl(PIPELINE_SERVICE_URL), ADMIN_AUTH_HEADERS);
// Update pipeline description and ingestion service that are null
CreatePipelineService update = create(test).withDescription("description1");
Schedule schedule = update.getIngestionSchedule();
Schedule schedule = new Schedule().withStartDate(new Date()).withRepeatFrequency("P1D");
CreatePipelineService update = createRequest(test).withDescription("description1").withIngestionSchedule(schedule);
ChangeDescription change = getChangeDescription(service.getVersion());
change.getFieldsAdded().add(new FieldChange().withName("description").withNewValue("description1"));
change.getFieldsAdded().add(new FieldChange().withName("ingestionSchedule").withNewValue(schedule));
service = updateAndCheckEntity(update, OK, adminAuthHeaders(), UpdateType.MINOR_UPDATE, change);
service = updateAndCheckEntity(update, OK, ADMIN_AUTH_HEADERS, UpdateType.MINOR_UPDATE, change);
// Update ingestion schedule again
Schedule schedule1 = new Schedule().withStartDate(new Date()).withRepeatFrequency("PT1H");
@ -196,7 +195,7 @@ public class PipelineServiceResourceTest extends EntityResourceTest<PipelineServ
change
.getFieldsUpdated()
.add(new FieldChange().withName("ingestionSchedule").withOldValue(schedule).withNewValue(schedule1));
service = updateAndCheckEntity(update, OK, adminAuthHeaders(), UpdateType.MINOR_UPDATE, change);
service = updateAndCheckEntity(update, OK, ADMIN_AUTH_HEADERS, UpdateType.MINOR_UPDATE, change);
// update pipeline Url
URI pipelineUrl = new URI("http://localhost:9000");
@ -205,53 +204,35 @@ public class PipelineServiceResourceTest extends EntityResourceTest<PipelineServ
change
.getFieldsUpdated()
.add(new FieldChange().withName("pipelineUrl").withOldValue(PIPELINE_SERVICE_URL).withNewValue(pipelineUrl));
updateAndCheckEntity(update, OK, adminAuthHeaders(), UpdateType.MINOR_UPDATE, change);
updateAndCheckEntity(update, OK, ADMIN_AUTH_HEADERS, UpdateType.MINOR_UPDATE, change);
}
@Test
void put_update_as_non_admin_401(TestInfo test) throws IOException {
Map<String, String> authHeaders = adminAuthHeaders();
createAndCheckEntity(create(test).withDescription(null).withIngestionSchedule(null), authHeaders);
createAndCheckEntity(createRequest(test).withDescription(null).withIngestionSchedule(null), ADMIN_AUTH_HEADERS);
// Update pipeline description and ingestion service that are null
HttpResponseException exception =
assertThrows(
HttpResponseException.class,
() ->
updateAndCheckEntity(
create(test), OK, authHeaders("test@open-metadata.org"), UpdateType.NO_CHANGE, null));
() -> updateAndCheckEntity(createRequest(test), OK, TEST_AUTH_HEADERS, UpdateType.NO_CHANGE, null));
TestUtils.assertResponse(exception, FORBIDDEN, "Principal: CatalogPrincipal{name='test'} " + "is not admin");
}
private CreatePipelineService create(TestInfo test) {
return create(getEntityName(test));
}
private CreatePipelineService create(TestInfo test, int index) {
return create(getEntityName(test, index));
}
private CreatePipelineService create(String name) {
@Override
public CreatePipelineService createRequest(
String name, String description, String displayName, EntityReference owner) {
return new CreatePipelineService()
.withName(name)
.withServiceType(CreatePipelineService.PipelineServiceType.Airflow)
.withPipelineUrl(PIPELINE_SERVICE_URL)
.withIngestionSchedule(new Schedule().withStartDate(new Date()).withRepeatFrequency("P1D"));
.withDescription(description)
.withIngestionSchedule(null);
}
@Override
public Object createRequest(String name, String description, String displayName, EntityReference owner) {
return create(name).withDescription(description).withIngestionSchedule(null);
}
@Override
public EntityReference getContainer(Object createRequest) throws URISyntaxException {
return null; // No container entity
}
@Override
public void validateCreatedEntity(PipelineService service, Object request, Map<String, String> authHeaders) {
CreatePipelineService createRequest = (CreatePipelineService) request;
public void validateCreatedEntity(
PipelineService service, CreatePipelineService createRequest, Map<String, String> authHeaders) {
validateCommonEntityFields(
getEntityInterface(service), createRequest.getDescription(), getPrincipal(authHeaders), null);
assertEquals(createRequest.getName(), service.getName());
@ -265,7 +246,8 @@ public class PipelineServiceResourceTest extends EntityResourceTest<PipelineServ
}
@Override
public void validateUpdatedEntity(PipelineService updatedEntity, Object request, Map<String, String> authHeaders) {
public void validateUpdatedEntity(
PipelineService updatedEntity, CreatePipelineService request, Map<String, String> authHeaders) {
validateCreatedEntity(updatedEntity, request, authHeaders);
}
@ -285,8 +267,8 @@ public class PipelineServiceResourceTest extends EntityResourceTest<PipelineServ
String fields = "";
service =
byName
? getEntityByName(service.getName(), null, fields, adminAuthHeaders())
: getEntity(service.getId(), fields, adminAuthHeaders());
? getEntityByName(service.getName(), fields, ADMIN_AUTH_HEADERS)
: getEntity(service.getId(), fields, ADMIN_AUTH_HEADERS);
TestUtils.assertListNotNull(
service.getHref(),
service.getVersion(),

View File

@ -17,12 +17,11 @@ import static javax.ws.rs.core.Response.Status.FORBIDDEN;
import static javax.ws.rs.core.Response.Status.OK;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.openmetadata.catalog.security.SecurityUtil.authHeaders;
import static org.openmetadata.catalog.util.TestUtils.adminAuthHeaders;
import static org.openmetadata.catalog.util.TestUtils.ADMIN_AUTH_HEADERS;
import static org.openmetadata.catalog.util.TestUtils.TEST_AUTH_HEADERS;
import static org.openmetadata.catalog.util.TestUtils.getPrincipal;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.HttpResponseException;
@ -41,7 +40,7 @@ import org.openmetadata.catalog.util.TestUtils;
import org.openmetadata.catalog.util.TestUtils.UpdateType;
@Slf4j
public class StorageServiceResourceTest extends EntityResourceTest<StorageService> {
public class StorageServiceResourceTest extends EntityResourceTest<StorageService, CreateStorageService> {
public StorageServiceResourceTest() {
super(
Entity.STORAGE_SERVICE,
@ -59,77 +58,60 @@ public class StorageServiceResourceTest extends EntityResourceTest<StorageServic
@Test
void post_validService_as_admin_200_ok(TestInfo test) throws IOException {
// Create storage service with different optional fields
Map<String, String> authHeaders = adminAuthHeaders();
createAndCheckEntity(create(test, 1).withDescription(null), authHeaders);
createAndCheckEntity(create(test, 2).withDescription("description"), authHeaders);
Map<String, String> authHeaders = ADMIN_AUTH_HEADERS;
createAndCheckEntity(createRequest(test, 1).withDescription(null), authHeaders);
createAndCheckEntity(createRequest(test, 2).withDescription("description"), authHeaders);
}
@Test
void post_validService_as_non_admin_401(TestInfo test) {
// Create storage service with different optional fields
Map<String, String> authHeaders = authHeaders("test@open-metadata.org");
HttpResponseException exception =
assertThrows(
HttpResponseException.class,
() -> createAndCheckEntity(create(test, 1).withDescription(null), authHeaders));
() -> createAndCheckEntity(createRequest(test, 1).withDescription(null), TEST_AUTH_HEADERS));
TestUtils.assertResponse(exception, FORBIDDEN, "Principal: CatalogPrincipal{name='test'} is not admin");
}
@Test
void put_updateStorageService_as_admin_2xx(TestInfo test) throws IOException {
createAndCheckEntity(create(test).withDescription(null), adminAuthHeaders());
createAndCheckEntity(createRequest(test).withDescription(null), ADMIN_AUTH_HEADERS);
// TODO add more tests for different fields
}
@Test
void put_update_as_non_admin_401(TestInfo test) throws IOException {
Map<String, String> authHeaders = adminAuthHeaders();
createAndCheckEntity(create(test).withDescription(null), authHeaders);
createAndCheckEntity(createRequest(test).withDescription(null), ADMIN_AUTH_HEADERS);
// Update storage description and ingestion service that are null
HttpResponseException exception =
assertThrows(
HttpResponseException.class,
() ->
updateAndCheckEntity(
create(test), OK, authHeaders("test@open-metadata.org"), UpdateType.NO_CHANGE, null));
() -> updateAndCheckEntity(createRequest(test), OK, TEST_AUTH_HEADERS, UpdateType.NO_CHANGE, null));
TestUtils.assertResponse(exception, FORBIDDEN, "Principal: CatalogPrincipal{name='test'} " + "is not admin");
}
private CreateStorageService create(TestInfo test) {
return create(getEntityName(test));
}
private CreateStorageService create(TestInfo test, int index) {
return create(getEntityName(test, index));
}
private CreateStorageService create(String name) {
return new CreateStorageService().withName(name).withServiceType(StorageServiceType.S3);
@Override
public CreateStorageService createRequest(
String name, String description, String displayName, EntityReference owner) {
return new CreateStorageService()
.withName(name)
.withServiceType(StorageServiceType.S3)
.withDescription(description);
}
@Override
public Object createRequest(String name, String description, String displayName, EntityReference owner) {
return create(name).withDescription(description);
}
@Override
public EntityReference getContainer(Object createRequest) throws URISyntaxException {
return null; // No container entity
}
@Override
public void validateCreatedEntity(StorageService service, Object request, Map<String, String> authHeaders) {
CreateStorageService createRequest = (CreateStorageService) request;
public void validateCreatedEntity(
StorageService service, CreateStorageService createRequest, Map<String, String> authHeaders) {
validateCommonEntityFields(
getEntityInterface(service), createRequest.getDescription(), getPrincipal(authHeaders), null);
assertEquals(createRequest.getName(), service.getName());
}
@Override
public void validateUpdatedEntity(StorageService service, Object request, Map<String, String> authHeaders) {
public void validateUpdatedEntity(
StorageService service, CreateStorageService request, Map<String, String> authHeaders) {
validateCreatedEntity(service, request, authHeaders);
}
@ -146,11 +128,10 @@ public class StorageServiceResourceTest extends EntityResourceTest<StorageServic
@Override
public void validateGetWithDifferentFields(StorageService service, boolean byName) throws HttpResponseException {
// No fields support
String fields = "";
service =
byName
? getEntityByName(service.getName(), null, fields, adminAuthHeaders())
: getEntity(service.getId(), fields, adminAuthHeaders());
? getEntityByName(service.getName(), "", ADMIN_AUTH_HEADERS)
: getEntity(service.getId(), "", ADMIN_AUTH_HEADERS);
TestUtils.assertListNotNull(
service.getHref(),
service.getVersion(),

View File

@ -21,7 +21,8 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.openmetadata.catalog.exception.CatalogExceptionMessage.entityNotFound;
import static org.openmetadata.catalog.security.SecurityUtil.authHeaders;
import static org.openmetadata.catalog.util.TestUtils.adminAuthHeaders;
import static org.openmetadata.catalog.util.TestUtils.ADMIN_AUTH_HEADERS;
import static org.openmetadata.catalog.util.TestUtils.TEST_AUTH_HEADERS;
import com.fasterxml.jackson.core.JsonProcessingException;
import java.io.IOException;
@ -50,8 +51,8 @@ import org.openmetadata.catalog.type.TagCategory;
import org.openmetadata.catalog.util.JsonUtils;
import org.openmetadata.catalog.util.TestUtils;
@Slf4j
/** Tests not covered here: Tag category and Tag usage counts are covered in TableResourceTest */
@Slf4j
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class TagResourceTest extends CatalogApplicationTest {
public static String BASE_URL;
@ -81,7 +82,7 @@ public class TagResourceTest extends CatalogApplicationTest {
@Test
void get_category_200() throws HttpResponseException {
// GET .../tags/{category} to get a category
TagCategory category = getCategory("User", authHeaders("test@open-metadata.org"));
TagCategory category = getCategory("User", TEST_AUTH_HEADERS);
assertEquals("User", category.getName());
validate(category);
}
@ -91,14 +92,14 @@ public class TagResourceTest extends CatalogApplicationTest {
// GET .../tags/{nonExistentCategory} returns 404
String nonExistent = "nonExistent";
HttpResponseException exception =
assertThrows(HttpResponseException.class, () -> getCategory(nonExistent, adminAuthHeaders()));
assertThrows(HttpResponseException.class, () -> getCategory(nonExistent, ADMIN_AUTH_HEADERS));
TestUtils.assertResponse(exception, NOT_FOUND, entityNotFound("TagCategory", nonExistent));
}
@Test
void get_validTag_200() throws HttpResponseException {
// GET .../tags/{category}/{tag} returns requested tag
Tag tag = getTag("User.Address", adminAuthHeaders());
Tag tag = getTag("User.Address", ADMIN_AUTH_HEADERS);
String parentURI = BASE_URL + "/User";
validateHRef(parentURI, tag);
}
@ -108,7 +109,7 @@ public class TagResourceTest extends CatalogApplicationTest {
// GET .../tags/{category}/{nonExistent} returns 404 Not found
String tagFQN = "User.NonExistent";
HttpResponseException exception =
assertThrows(HttpResponseException.class, () -> getTag(tagFQN, adminAuthHeaders()));
assertThrows(HttpResponseException.class, () -> getTag(tagFQN, ADMIN_AUTH_HEADERS));
TestUtils.assertResponse(exception, NOT_FOUND, entityNotFound("Tag", tagFQN));
}
@ -121,7 +122,7 @@ public class TagResourceTest extends CatalogApplicationTest {
.withDescription("description")
.withCategoryType(TagCategoryType.Descriptive);
HttpResponseException exception =
assertThrows(HttpResponseException.class, () -> createAndCheckCategory(create, adminAuthHeaders()));
assertThrows(HttpResponseException.class, () -> createAndCheckCategory(create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponse(exception, CONFLICT, "Entity already exists");
}
@ -134,7 +135,7 @@ public class TagResourceTest extends CatalogApplicationTest {
.withName(categoryName)
.withDescription("description")
.withCategoryType(TagCategoryType.Descriptive);
TagCategory newCategory = createAndCheckCategory(create, adminAuthHeaders());
TagCategory newCategory = createAndCheckCategory(create, ADMIN_AUTH_HEADERS);
assertEquals(0, newCategory.getChildren().size());
}
@ -150,17 +151,17 @@ public class TagResourceTest extends CatalogApplicationTest {
.withDescription(null)
.withCategoryType(TagCategoryType.Descriptive);
HttpResponseException exception =
assertThrows(HttpResponseException.class, () -> createAndCheckCategory(create, adminAuthHeaders()));
assertThrows(HttpResponseException.class, () -> createAndCheckCategory(create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponseContains(exception, BAD_REQUEST, "description must not be null");
// Missing category
create.withDescription("description").withCategoryType(null);
exception = assertThrows(HttpResponseException.class, () -> createAndCheckCategory(create, adminAuthHeaders()));
exception = assertThrows(HttpResponseException.class, () -> createAndCheckCategory(create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponseContains(exception, BAD_REQUEST, "categoryType must not be null");
// Long name
create.withName(TestUtils.LONG_ENTITY_NAME).withCategoryType(TagCategoryType.Descriptive);
exception = assertThrows(HttpResponseException.class, () -> createAndCheckCategory(create, adminAuthHeaders()));
exception = assertThrows(HttpResponseException.class, () -> createAndCheckCategory(create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponseContains(exception, BAD_REQUEST, "name size must be between 2 and 25");
}
@ -170,15 +171,15 @@ public class TagResourceTest extends CatalogApplicationTest {
// POST .../tags/{category}/{primaryTag} to create primary tag
TagCategory category = getCategory("User", authHeaders("test@open-meatadata.org"));
CreateTag create = new CreateTag().withName("PrimaryTag").withDescription("description");
createPrimaryTag(category.getName(), create, adminAuthHeaders());
TagCategory returnedCategory = getCategory("User", authHeaders("test@open-metadata.org"));
createPrimaryTag(category.getName(), create, ADMIN_AUTH_HEADERS);
TagCategory returnedCategory = getCategory("User", TEST_AUTH_HEADERS);
// Ensure the tag category "User" has one more additional tag to account for newly created tag
assertEquals(category.getChildren().size() + 1, returnedCategory.getChildren().size());
// POST .../tags/{category}/{primaryTag}/{secondaryTag} to create secondary tag
create = new CreateTag().withName("SecondaryTag").withDescription("description");
createSecondaryTag(category.getName(), "PrimaryTag", create, adminAuthHeaders());
createSecondaryTag(category.getName(), "PrimaryTag", create, ADMIN_AUTH_HEADERS);
}
@Test
@ -186,24 +187,24 @@ public class TagResourceTest extends CatalogApplicationTest {
// Missing description in POST primary tag
CreateTag create = new CreateTag().withName("noDescription").withDescription(null);
HttpResponseException exception =
assertThrows(HttpResponseException.class, () -> createPrimaryTag("User", create, adminAuthHeaders()));
assertThrows(HttpResponseException.class, () -> createPrimaryTag("User", create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponseContains(exception, BAD_REQUEST, "description must not be null");
// Missing description in POST secondary tag
exception =
assertThrows(
HttpResponseException.class, () -> createSecondaryTag("User", "Address", create, adminAuthHeaders()));
HttpResponseException.class, () -> createSecondaryTag("User", "Address", create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponseContains(exception, BAD_REQUEST, "description must not be null");
// Long primary tag name
create.withDescription("description").withName(TestUtils.LONG_ENTITY_NAME);
exception = assertThrows(HttpResponseException.class, () -> createPrimaryTag("User", create, adminAuthHeaders()));
exception = assertThrows(HttpResponseException.class, () -> createPrimaryTag("User", create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponseContains(exception, BAD_REQUEST, "name size must be between 2 and 25");
// Long secondary tag name
exception =
assertThrows(
HttpResponseException.class, () -> createSecondaryTag("User", "Address", create, adminAuthHeaders()));
HttpResponseException.class, () -> createSecondaryTag("User", "Address", create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponseContains(exception, BAD_REQUEST, "name size must be between 2 and 25");
}
@ -213,13 +214,13 @@ public class TagResourceTest extends CatalogApplicationTest {
String nonExistent = "nonExistent";
CreateTag create = new CreateTag().withName("primary").withDescription("description");
HttpResponseException exception =
assertThrows(HttpResponseException.class, () -> createPrimaryTag(nonExistent, create, adminAuthHeaders()));
assertThrows(HttpResponseException.class, () -> createPrimaryTag(nonExistent, create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponse(exception, NOT_FOUND, entityNotFound("TagCategory", nonExistent));
// POST .../tags/{user}/{nonExistent}/tag where primaryTag does not exist
exception =
assertThrows(
HttpResponseException.class, () -> createSecondaryTag("User", nonExistent, create, adminAuthHeaders()));
HttpResponseException.class, () -> createSecondaryTag("User", nonExistent, create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponse(exception, NOT_FOUND, entityNotFound("Tag", nonExistent));
}
@ -232,11 +233,11 @@ public class TagResourceTest extends CatalogApplicationTest {
.withName(newCategoryName)
.withDescription("updatedDescription")
.withCategoryType(TagCategoryType.Descriptive);
updateCategory("User", create, adminAuthHeaders());
updateCategory("User", create, ADMIN_AUTH_HEADERS);
// Revert tag category back
create.withName("User").withCategoryType(TagCategoryType.Classification);
updateCategory(newCategoryName, create, adminAuthHeaders());
updateCategory(newCategoryName, create, ADMIN_AUTH_HEADERS);
}
@Test
@ -249,12 +250,12 @@ public class TagResourceTest extends CatalogApplicationTest {
.withDescription(null)
.withCategoryType(TagCategoryType.Descriptive);
HttpResponseException exception =
assertThrows(HttpResponseException.class, () -> updateCategory("User", create, adminAuthHeaders()));
assertThrows(HttpResponseException.class, () -> updateCategory("User", create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponseContains(exception, BAD_REQUEST, "description must not be null");
// Long primary tag name
create.withDescription("description").withName(TestUtils.LONG_ENTITY_NAME);
exception = assertThrows(HttpResponseException.class, () -> updateCategory("User", create, adminAuthHeaders()));
exception = assertThrows(HttpResponseException.class, () -> updateCategory("User", create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponseContains(exception, BAD_REQUEST, "name size must be between 2 and 25");
}
@ -262,22 +263,22 @@ public class TagResourceTest extends CatalogApplicationTest {
void put_primaryTag_200() throws HttpResponseException, JsonProcessingException {
// PUT .../tags/{user}/{address} update the tag
CreateTag create = new CreateTag().withName("AddressUpdated").withDescription("updatedDescription");
updatePrimaryTag("User", "Address", create, adminAuthHeaders());
updatePrimaryTag("User", "Address", create, ADMIN_AUTH_HEADERS);
// Revert to old tag name user.address from user.addressUpdated
create.withName("Address");
updatePrimaryTag("User", "AddressUpdated", create, adminAuthHeaders());
updatePrimaryTag("User", "AddressUpdated", create, ADMIN_AUTH_HEADERS);
}
@Test
void put_secondaryTag_200() throws HttpResponseException, JsonProcessingException {
// PUT .../tags/{user}/{primaryTag}/{secondaryTag} update the tag
CreateTag create = new CreateTag().withName("SecondaryTag1").withDescription("description");
updateSecondaryTag("User", "PrimaryTag", "SecondaryTag", create, adminAuthHeaders());
updateSecondaryTag("User", "PrimaryTag", "SecondaryTag", create, ADMIN_AUTH_HEADERS);
// Revert to old tag name user.primaryTag.secondaryTag from user.primaryTag.secondaryTag1
create.withName("SecondaryTag");
updateSecondaryTag("User", "PrimaryTag", "SecondaryTag1", create, adminAuthHeaders());
updateSecondaryTag("User", "PrimaryTag", "SecondaryTag1", create, ADMIN_AUTH_HEADERS);
}
@Test
@ -286,28 +287,28 @@ public class TagResourceTest extends CatalogApplicationTest {
CreateTag create = new CreateTag().withName("AddressUpdated").withDescription(null);
HttpResponseException exception =
assertThrows(
HttpResponseException.class, () -> updatePrimaryTag("User", "Address", create, adminAuthHeaders()));
HttpResponseException.class, () -> updatePrimaryTag("User", "Address", create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponseContains(exception, BAD_REQUEST, "description must not be null");
// Secondar tag with missing description
exception =
assertThrows(
HttpResponseException.class,
() -> updateSecondaryTag("User", "Address", "Secondary", create, adminAuthHeaders()));
() -> updateSecondaryTag("User", "Address", "Secondary", create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponseContains(exception, BAD_REQUEST, "description must not be null");
// Long primary tag name
create.withDescription("description").withName(TestUtils.LONG_ENTITY_NAME);
exception =
assertThrows(
HttpResponseException.class, () -> updatePrimaryTag("User", "Address", create, adminAuthHeaders()));
HttpResponseException.class, () -> updatePrimaryTag("User", "Address", create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponseContains(exception, BAD_REQUEST, "name size must be between 2 and 25");
// Long secondary tag name
exception =
assertThrows(
HttpResponseException.class,
() -> updateSecondaryTag("User", "Address", "Secondary", create, adminAuthHeaders()));
() -> updateSecondaryTag("User", "Address", "Secondary", create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponseContains(exception, BAD_REQUEST, "name size must be between 2 and 25");
}
@ -434,7 +435,7 @@ public class TagResourceTest extends CatalogApplicationTest {
public static CategoryList listCategories() throws HttpResponseException {
WebTarget target = getResource("tags");
return TestUtils.get(target, CategoryList.class, authHeaders("test@open-metadata.org"));
return TestUtils.get(target, CategoryList.class, TEST_AUTH_HEADERS);
}
public static TagCategory getCategory(String category, Map<String, String> autHeaders) throws HttpResponseException {

View File

@ -16,26 +16,21 @@ package org.openmetadata.catalog.resources.teams;
import static javax.ws.rs.core.Response.Status.FORBIDDEN;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.openmetadata.catalog.security.SecurityUtil.authHeaders;
import static org.openmetadata.catalog.util.TestUtils.adminAuthHeaders;
import static org.openmetadata.catalog.util.TestUtils.ADMIN_AUTH_HEADERS;
import static org.openmetadata.catalog.util.TestUtils.TEST_AUTH_HEADERS;
import static org.openmetadata.catalog.util.TestUtils.assertListNotNull;
import static org.openmetadata.catalog.util.TestUtils.assertResponse;
import com.fasterxml.jackson.core.JsonProcessingException;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.ws.rs.client.WebTarget;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.HttpResponseException;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
import org.openmetadata.catalog.CatalogApplicationTest;
import org.openmetadata.catalog.Entity;
import org.openmetadata.catalog.api.teams.CreateRole;
import org.openmetadata.catalog.api.teams.CreateTeam;
import org.openmetadata.catalog.entity.policies.Policy;
import org.openmetadata.catalog.entity.teams.Role;
import org.openmetadata.catalog.jdbi3.RoleRepository.RoleEntityInterface;
@ -49,7 +44,7 @@ import org.openmetadata.catalog.util.JsonUtils;
import org.openmetadata.catalog.util.TestUtils;
@Slf4j
public class RoleResourceTest extends EntityResourceTest<Role> {
public class RoleResourceTest extends EntityResourceTest<Role, CreateRole> {
public RoleResourceTest() {
super(Entity.ROLE, Role.class, RoleList.class, "roles", null, false, false, false, false);
@ -58,22 +53,22 @@ public class RoleResourceTest extends EntityResourceTest<Role> {
@Test
void post_validRoles_as_admin_200_OK(TestInfo test) throws IOException {
// Create role with different optional fields
CreateRole create = create(test, 1);
createAndCheckRole(create, adminAuthHeaders());
CreateRole create = createRequest(test, 1);
createAndCheckRole(create, ADMIN_AUTH_HEADERS);
create = create(test, 2).withDisplayName("displayName");
createAndCheckRole(create, adminAuthHeaders());
create = createRequest(test, 2).withDisplayName("displayName");
createAndCheckRole(create, ADMIN_AUTH_HEADERS);
create = create(test, 3).withDescription("description");
createAndCheckRole(create, adminAuthHeaders());
create = createRequest(test, 3).withDescription("description");
createAndCheckRole(create, ADMIN_AUTH_HEADERS);
create = create(test, 4).withDisplayName("displayName").withDescription("description");
createAndCheckRole(create, adminAuthHeaders());
create = createRequest(test, 4).withDisplayName("displayName").withDescription("description");
createAndCheckRole(create, ADMIN_AUTH_HEADERS);
}
private Role createAndCheckRole(CreateRole create, Map<String, String> authHeaders) throws IOException {
Role role = createAndCheckEntity(create, authHeaders);
Policy policy = PolicyResourceTest.getPolicy(role.getPolicy().getId(), PolicyResource.FIELDS, adminAuthHeaders());
Policy policy = PolicyResourceTest.getPolicy(role.getPolicy().getId(), PolicyResource.FIELDS, ADMIN_AUTH_HEADERS);
assertEquals(String.format("%sRoleAccessControlPolicy", role.getName()), policy.getName());
assertEquals(String.format("%s Role Access Control Policy", role.getDisplayName()), policy.getDisplayName());
assertEquals(
@ -85,44 +80,25 @@ public class RoleResourceTest extends EntityResourceTest<Role> {
@Test
void post_validRoles_as_non_admin_401(TestInfo test) {
// Create role with different optional fields
Map<String, String> authHeaders = authHeaders("test@open-metadata.org");
CreateRole create = create(test, 1);
CreateRole create = createRequest(test, 1);
HttpResponseException exception =
assertThrows(HttpResponseException.class, () -> createAndCheckRole(create, authHeaders));
assertThrows(HttpResponseException.class, () -> createAndCheckRole(create, TEST_AUTH_HEADERS));
assertResponse(exception, FORBIDDEN, "Principal: CatalogPrincipal{name='test'} is not admin");
}
@Test
void patch_roleAttributes_as_non_admin_403(TestInfo test) throws HttpResponseException, JsonProcessingException {
// Create table without any attributes
Role role = createRole(create(test), adminAuthHeaders());
Role role = createEntity(createRequest(test), ADMIN_AUTH_HEADERS);
// Patching as a non-admin should is disallowed
String originalJson = JsonUtils.pojoToJson(role);
role.setDisplayName("newDisplayName");
HttpResponseException exception =
assertThrows(
HttpResponseException.class,
() -> patchEntity(role.getId(), originalJson, role, authHeaders("test@open-metadata.org")));
HttpResponseException.class, () -> patchEntity(role.getId(), originalJson, role, TEST_AUTH_HEADERS));
assertResponse(exception, FORBIDDEN, "Principal: CatalogPrincipal{name='test'} is not admin");
}
public static Role createRole(CreateRole create, Map<String, String> authHeaders) throws HttpResponseException {
return TestUtils.post(CatalogApplicationTest.getResource("roles"), create, Role.class, authHeaders);
}
public static Role getRole(UUID id, String fields, Map<String, String> authHeaders) throws HttpResponseException {
WebTarget target = CatalogApplicationTest.getResource("roles/" + id);
target = fields != null ? target.queryParam("fields", fields) : target;
return TestUtils.get(target, Role.class, authHeaders);
}
public static Role getRoleByName(String name, String fields, Map<String, String> authHeaders)
throws HttpResponseException {
WebTarget target = CatalogApplicationTest.getResource("roles/name/" + name);
target = fields != null ? target.queryParam("fields", fields) : target;
return TestUtils.get(target, Role.class, authHeaders);
}
private static void validateRole(
Role role, String expectedDescription, String expectedDisplayName, String expectedUpdatedBy) {
assertListNotNull(role.getId(), role.getHref());
@ -134,64 +110,45 @@ public class RoleResourceTest extends EntityResourceTest<Role> {
@Override
protected void prepareGetWithDifferentFields(Role role) throws HttpResponseException {
// Assign two arbitrary users this role for testing.
UserResourceTest.createUser(
UserResourceTest.create(role.getName() + "user1").withRoles(List.of(role.getId())), adminAuthHeaders());
UserResourceTest.createUser(
UserResourceTest.create(role.getName() + "user2").withRoles(List.of(role.getId())), adminAuthHeaders());
UserResourceTest userResourceTest = new UserResourceTest();
userResourceTest.createEntity(
userResourceTest.createRequest(role.getName() + "user1", "", "", null).withRoles(List.of(role.getId())),
ADMIN_AUTH_HEADERS);
userResourceTest.createEntity(
userResourceTest.createRequest(role.getName() + "user2", "", "", null).withRoles(List.of(role.getId())),
ADMIN_AUTH_HEADERS);
}
/** Validate returned fields GET .../roles/{id}?fields="..." or GET .../roles/name/{name}?fields="..." */
@Override
public void validateGetWithDifferentFields(Role expectedRole, boolean byName) throws HttpResponseException {
String updatedBy = TestUtils.getPrincipal(adminAuthHeaders());
String updatedBy = TestUtils.getPrincipal(ADMIN_AUTH_HEADERS);
// .../roles
Role role =
byName
? getRoleByName(expectedRole.getName(), null, adminAuthHeaders())
: getRole(expectedRole.getId(), null, adminAuthHeaders());
? getEntityByName(expectedRole.getName(), null, ADMIN_AUTH_HEADERS)
: getEntity(expectedRole.getId(), null, ADMIN_AUTH_HEADERS);
validateRole(role, expectedRole.getDescription(), expectedRole.getDisplayName(), updatedBy);
// .../roles?fields=policy,users
String fields = "policy,users";
role =
byName
? getRoleByName(expectedRole.getName(), fields, adminAuthHeaders())
: getRole(expectedRole.getId(), fields, adminAuthHeaders());
? getEntityByName(expectedRole.getName(), null, fields, ADMIN_AUTH_HEADERS)
: getEntity(expectedRole.getId(), fields, ADMIN_AUTH_HEADERS);
validateRole(role, expectedRole.getDescription(), expectedRole.getDisplayName(), updatedBy);
TestUtils.validateEntityReference(role.getPolicy());
TestUtils.validateEntityReference(role.getUsers());
}
public static Role createRole(CreateTeam create, Map<String, String> authHeaders) throws HttpResponseException {
return TestUtils.post(CatalogApplicationTest.getResource("roles"), create, Role.class, authHeaders);
}
CreateRole create(TestInfo test, int index) {
return new CreateRole().withName(getEntityName(test) + index);
}
public CreateRole create(TestInfo test) {
return create(getEntityName(test));
}
public CreateRole create(String name) {
return new CreateRole().withName(name);
@Override
public CreateRole createRequest(String name, String description, String displayName, EntityReference owner) {
return new CreateRole().withName(name).withDescription(description).withDisplayName(displayName);
}
@Override
public Object createRequest(String name, String description, String displayName, EntityReference owner) {
return create(name).withDescription(description).withDisplayName(displayName);
}
@Override
public EntityReference getContainer(Object createRequest) throws URISyntaxException {
return null;
}
@Override
public void validateCreatedEntity(Role role, Object request, Map<String, String> authHeaders) {
CreateRole createRequest = (CreateRole) request;
public void validateCreatedEntity(Role role, CreateRole createRequest, Map<String, String> authHeaders) {
validateCommonEntityFields(
getEntityInterface(role), createRequest.getDescription(), TestUtils.getPrincipal(authHeaders), null);
@ -199,7 +156,7 @@ public class RoleResourceTest extends EntityResourceTest<Role> {
}
@Override
public void validateUpdatedEntity(Role updatedEntity, Object request, Map<String, String> authHeaders) {
public void validateUpdatedEntity(Role updatedEntity, CreateRole request, Map<String, String> authHeaders) {
validateCreatedEntity(updatedEntity, request, authHeaders);
}

View File

@ -20,9 +20,8 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.openmetadata.catalog.resources.teams.UserResourceTest.createUser;
import static org.openmetadata.catalog.security.SecurityUtil.authHeaders;
import static org.openmetadata.catalog.util.TestUtils.adminAuthHeaders;
import static org.openmetadata.catalog.util.TestUtils.ADMIN_AUTH_HEADERS;
import static org.openmetadata.catalog.util.TestUtils.TEST_AUTH_HEADERS;
import static org.openmetadata.catalog.util.TestUtils.assertListNotNull;
import static org.openmetadata.catalog.util.TestUtils.assertResponse;
import static org.openmetadata.catalog.util.TestUtils.validateEntityReference;
@ -30,7 +29,6 @@ import static org.openmetadata.catalog.util.TestUtils.validateEntityReference;
import com.fasterxml.jackson.core.JsonProcessingException;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@ -38,13 +36,10 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import javax.json.JsonPatch;
import javax.ws.rs.client.WebTarget;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.HttpResponseException;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
import org.openmetadata.catalog.CatalogApplicationTest;
import org.openmetadata.catalog.Entity;
import org.openmetadata.catalog.api.teams.CreateTeam;
import org.openmetadata.catalog.entity.teams.Team;
@ -63,7 +58,7 @@ import org.openmetadata.catalog.util.JsonUtils;
import org.openmetadata.catalog.util.TestUtils;
@Slf4j
public class TeamResourceTest extends EntityResourceTest<Team> {
public class TeamResourceTest extends EntityResourceTest<Team, CreateTeam> {
final Profile PROFILE = new Profile().withImages(new ImageList().withImage(URI.create("http://image.com")));
public TeamResourceTest() {
@ -73,29 +68,27 @@ public class TeamResourceTest extends EntityResourceTest<Team> {
@Test
void post_validTeams_as_admin_200_OK(TestInfo test) throws IOException {
// Create team with different optional fields
CreateTeam create = create(test, 1);
createAndCheckEntity(create, adminAuthHeaders());
CreateTeam create = createRequest(test, 1);
createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
create = create(test, 2).withDisplayName("displayName");
createAndCheckEntity(create, adminAuthHeaders());
create = createRequest(test, 2).withDisplayName("displayName");
createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
create = create(test, 3).withDescription("description");
createAndCheckEntity(create, adminAuthHeaders());
create = createRequest(test, 3).withDescription("description");
createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
create = create(test, 4).withProfile(PROFILE);
createAndCheckEntity(create, adminAuthHeaders());
create = createRequest(test, 4).withProfile(PROFILE);
createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
create = create(test, 5).withDisplayName("displayName").withDescription("description").withProfile(PROFILE);
createAndCheckEntity(create, adminAuthHeaders());
create = createRequest(test, 5).withDisplayName("displayName").withDescription("description").withProfile(PROFILE);
createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
}
@Test
void post_validTeams_as_non_admin_401(TestInfo test) {
// Create team with different optional fields
Map<String, String> authHeaders = authHeaders("test@open-metadata.org");
CreateTeam create = create(test, 1);
HttpResponseException exception =
assertThrows(HttpResponseException.class, () -> createAndCheckEntity(create, authHeaders));
assertThrows(HttpResponseException.class, () -> createAndCheckEntity(createRequest(test), TEST_AUTH_HEADERS));
assertResponse(exception, FORBIDDEN, "Principal: CatalogPrincipal{name='test'} is not admin");
}
@ -103,141 +96,72 @@ public class TeamResourceTest extends EntityResourceTest<Team> {
void post_teamWithUsers_200_OK(TestInfo test) throws IOException {
// Add team to user relationships while creating a team
UserResourceTest userResourceTest = new UserResourceTest();
User user1 = createUser(userResourceTest.create(test, 1), authHeaders("test@open-metadata.org"));
User user2 = createUser(userResourceTest.create(test, 2), authHeaders("test@open-metadata.org"));
User user1 = userResourceTest.createEntity(userResourceTest.createRequest(test, 1), TEST_AUTH_HEADERS);
User user2 = userResourceTest.createEntity(userResourceTest.createRequest(test, 2), TEST_AUTH_HEADERS);
List<UUID> users = Arrays.asList(user1.getId(), user2.getId());
CreateTeam create =
create(test)
createRequest(test)
.withDisplayName("displayName")
.withDescription("description")
.withProfile(PROFILE)
.withUsers(users);
Team team = createAndCheckEntity(create, adminAuthHeaders());
Team team = createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
// Make sure the user entity has relationship to the team
user1 = userResourceTest.getEntity(user1.getId(), "teams", authHeaders("test@open-metadata.org"));
user1 = userResourceTest.getEntity(user1.getId(), "teams", TEST_AUTH_HEADERS);
assertEquals(team.getId(), user1.getTeams().get(0).getId());
user2 = userResourceTest.getEntity(user2.getId(), "teams", authHeaders("test@open-metadata.org"));
user2 = userResourceTest.getEntity(user2.getId(), "teams", TEST_AUTH_HEADERS);
assertEquals(team.getId(), user2.getTeams().get(0).getId());
}
@Test
void get_teamWithInvalidFields_400_BadRequest(TestInfo test) throws HttpResponseException {
CreateTeam create = create(test);
Team team = createTeam(create, adminAuthHeaders());
CreateTeam create = createRequest(test);
Team team = createEntity(create, ADMIN_AUTH_HEADERS);
// Empty query field .../teams?fields=
HttpResponseException exception =
assertThrows(HttpResponseException.class, () -> getTeam(team.getId(), "test", adminAuthHeaders()));
assertThrows(HttpResponseException.class, () -> getEntity(team.getId(), "test", ADMIN_AUTH_HEADERS));
assertResponse(exception, BAD_REQUEST, CatalogExceptionMessage.invalidField("test"));
// .../teams?fields=invalidField
exception =
assertThrows(HttpResponseException.class, () -> getTeam(team.getId(), "invalidField", adminAuthHeaders()));
assertThrows(HttpResponseException.class, () -> getEntity(team.getId(), "invalidField", ADMIN_AUTH_HEADERS));
assertResponse(exception, BAD_REQUEST, CatalogExceptionMessage.invalidField("invalidField"));
}
/**
* @see EntityResourceTest#put_addDeleteFollower_200 for tests related getting team with entities owned by the team
* @see EntityResourceTest put_addDeleteFollower_200 for tests related getting team with entities owned by the team
*/
@Test
void delete_validTeam_200_OK(TestInfo test) throws IOException {
UserResourceTest userResourceTest = new UserResourceTest();
User user1 = createUser(userResourceTest.create(test, 1), adminAuthHeaders());
User user1 = userResourceTest.createEntity(userResourceTest.createRequest(test, 1), ADMIN_AUTH_HEADERS);
List<UUID> users = Collections.singletonList(user1.getId());
CreateTeam create = create(test).withUsers(users);
Team team = createAndCheckEntity(create, adminAuthHeaders());
CreateTeam create = createRequest(test).withUsers(users);
Team team = createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
// Team with users can be deleted - Team -- has --> User relationships are deleted
deleteAndCheckEntity(team, adminAuthHeaders());
deleteAndCheckEntity(team, ADMIN_AUTH_HEADERS);
// Make sure user does not have relationship to this team
User user = userResourceTest.getEntity(user1.getId(), "teams", adminAuthHeaders());
User user = userResourceTest.getEntity(user1.getId(), "teams", ADMIN_AUTH_HEADERS);
assertTrue(user.getTeams().isEmpty());
}
// @Test
// public void patch_teamAttributes_as_admin_200_ok(TestInfo test)
// throws HttpResponseException, JsonProcessingException {
// //
// // Create table without any attributes
// //
// Team team = createTeam(create(test), adminAuthHeaders());
// assertNull(team.getDisplayName());
// assertNull(team.getDescription());
// assertNull(team.getProfile());
// assertNull(team.getDeleted());
// assertNull(team.getUsers());
//
// User user1 = createUser(UserResourceTest.create(test, 1), authHeaders("test@open-metadata.org"));
// User user2 = createUser(UserResourceTest.create(test, 2), authHeaders("test@open-metadata.org"));
// User user3 = createUser(UserResourceTest.create(test, 3), authHeaders("test@open-metadata.org"));
//
// List<EntityReference> users = Arrays.asList(new UserEntityInterface(user1).getEntityReference(),
// new UserEntityInterface(user2).getEntityReference());
// Profile profile = new Profile().withImages(new ImageList().withImage(URI.create("http://image.com")));
//
// //
// // Add previously absent attributes
// //
// String originalJson = JsonUtils.pojoToJson(team);
// team.withDisplayName("displayName").withDescription("description").withProfile(profile).withUsers(users);
// ChangeDescription change = getChangeDescription(team.getVersion())
// .withFieldsAdded(Arrays.asList("displayName", "description", "profile", "users"));
// team = patchEntityAndCheck(team, originalJson, adminAuthHeaders(), MINOR_UPDATE, change);
//
// //
// // Replace the attributes
// //
// users = Arrays.asList(new UserEntityInterface(user1).getEntityReference(),
// new UserEntityInterface(user3).getEntityReference()); // user2 dropped and user3 is added
// profile = new Profile().withImages(new ImageList().withImage(URI.create("http://image1.com")));
//
// originalJson = JsonUtils.pojoToJson(team);
// team.withDisplayName("displayName1").withDescription("description1").withProfile(profile).withUsers(users);
// change = getChangeDescription(team.getVersion())
// .withFieldsUpdated(Arrays.asList("displayName", "description", "profile", "users"));
// team = patchEntityAndCheck(team, originalJson, adminAuthHeaders(), MINOR_UPDATE, change);
//
// // Remove the attributes
// originalJson = JsonUtils.pojoToJson(team);
// team.withDisplayName(null).withDescription(null).withProfile(null).withUsers(null);
// change = getChangeDescription(team.getVersion())
// .withFieldsDeleted(Arrays.asList("displayName", "description", "profile", "users"));
// patchEntityAndCheck(team, originalJson, adminAuthHeaders(), MINOR_UPDATE, change);
// }
@Test
void patch_teamAttributes_as_non_admin_403(TestInfo test) throws HttpResponseException, JsonProcessingException {
// Create table without any attributes
Team team = createTeam(create(test), adminAuthHeaders());
Team team = createEntity(createRequest(test), ADMIN_AUTH_HEADERS);
// Patching as a non-admin should is disallowed
String originalJson = JsonUtils.pojoToJson(team);
team.setDisplayName("newDisplayName");
HttpResponseException exception =
assertThrows(
HttpResponseException.class,
() -> patchTeam(team.getId(), originalJson, team, authHeaders("test@open-metadata.org")));
HttpResponseException.class, () -> patchEntity(team.getId(), originalJson, team, TEST_AUTH_HEADERS));
assertResponse(exception, FORBIDDEN, "Principal: CatalogPrincipal{name='test'} is not admin");
}
public static Team createTeam(CreateTeam create, Map<String, String> authHeaders) throws HttpResponseException {
return TestUtils.post(CatalogApplicationTest.getResource("teams"), create, Team.class, authHeaders);
}
public static Team getTeam(UUID id, String fields, Map<String, String> authHeaders) throws HttpResponseException {
WebTarget target = CatalogApplicationTest.getResource("teams/" + id);
target = fields != null ? target.queryParam("fields", fields) : target;
return TestUtils.get(target, Team.class, authHeaders);
}
public static Team getTeamByName(String name, String fields, Map<String, String> authHeaders)
throws HttpResponseException {
WebTarget target = CatalogApplicationTest.getResource("teams/name/" + name);
target = fields != null ? target.queryParam("fields", fields) : target;
return TestUtils.get(target, Team.class, authHeaders);
}
private static void validateTeam(
Team team,
String expectedDescription,
@ -263,13 +187,13 @@ public class TeamResourceTest extends EntityResourceTest<Team> {
/** Validate returned fields GET .../teams/{id}?fields="..." or GET .../teams/name/{name}?fields="..." */
@Override
public void validateGetWithDifferentFields(Team expectedTeam, boolean byName) throws HttpResponseException {
String updatedBy = TestUtils.getPrincipal(adminAuthHeaders());
String updatedBy = TestUtils.getPrincipal(ADMIN_AUTH_HEADERS);
// .../teams?fields=profile
String fields = "profile";
Team getTeam =
byName
? getTeamByName(expectedTeam.getName(), fields, adminAuthHeaders())
: getTeam(expectedTeam.getId(), fields, adminAuthHeaders());
? getEntityByName(expectedTeam.getName(), fields, ADMIN_AUTH_HEADERS)
: getEntity(expectedTeam.getId(), null, fields, ADMIN_AUTH_HEADERS);
validateTeam(
getTeam,
expectedTeam.getDescription(),
@ -283,44 +207,20 @@ public class TeamResourceTest extends EntityResourceTest<Team> {
fields = "users,owns,profile";
getTeam =
byName
? getTeamByName(expectedTeam.getName(), fields, adminAuthHeaders())
: getTeam(expectedTeam.getId(), fields, adminAuthHeaders());
? getEntityByName(expectedTeam.getName(), fields, ADMIN_AUTH_HEADERS)
: getEntity(expectedTeam.getId(), fields, ADMIN_AUTH_HEADERS);
assertNotNull(getTeam.getProfile());
validateEntityReference(getTeam.getUsers());
validateEntityReference(getTeam.getOwns());
}
private Team patchTeam(UUID teamId, String originalJson, Team updated, Map<String, String> authHeaders)
throws JsonProcessingException, HttpResponseException {
String updatedJson = JsonUtils.pojoToJson(updated);
JsonPatch patch = JsonUtils.getJsonPatch(originalJson, updatedJson);
return TestUtils.patch(CatalogApplicationTest.getResource("teams/" + teamId), patch, Team.class, authHeaders);
}
private Team patchTeam(String originalJson, Team updated, Map<String, String> authHeaders)
throws JsonProcessingException, HttpResponseException {
return patchTeam(updated.getId(), originalJson, updated, authHeaders);
}
CreateTeam create(TestInfo test, int index) {
return new CreateTeam().withName(getEntityName(test) + index);
}
public CreateTeam create(TestInfo test) {
return create(getEntityName(test));
}
public CreateTeam create(String name) {
return new CreateTeam().withName(name);
}
@Override
public Object createRequest(String name, String description, String displayName, EntityReference owner) {
return create(name)
public CreateTeam createRequest(String name, String description, String displayName, EntityReference owner) {
return new CreateTeam()
.withName(name)
.withDescription(description)
.withDisplayName(displayName)
.withProfile(PROFILE)
.withUsers(List.of(USER1.getId()));
.withProfile(PROFILE);
}
@Override
@ -328,18 +228,12 @@ public class TeamResourceTest extends EntityResourceTest<Team> {
LocationResourceTest locationResourceTest = new LocationResourceTest();
EntityReference teamRef = new EntityReference().withId(team.getId()).withType("team");
locationResourceTest.createEntity(
locationResourceTest.createRequest(getEntityName(test), null, null, teamRef), adminAuthHeaders());
locationResourceTest.createRequest(getEntityName(test), null, null, teamRef), ADMIN_AUTH_HEADERS);
return team;
}
@Override
public EntityReference getContainer(Object createRequest) throws URISyntaxException {
return null; // No container entity
}
@Override
public void validateCreatedEntity(Team team, Object request, Map<String, String> authHeaders) {
CreateTeam createRequest = (CreateTeam) request;
public void validateCreatedEntity(Team team, CreateTeam createRequest, Map<String, String> authHeaders) {
validateCommonEntityFields(
getEntityInterface(team), createRequest.getDescription(), TestUtils.getPrincipal(authHeaders), null);
@ -361,13 +255,13 @@ public class TeamResourceTest extends EntityResourceTest<Team> {
}
@Override
public void validateUpdatedEntity(Team updatedEntity, Object request, Map<String, String> authHeaders) {
public void validateUpdatedEntity(Team updatedEntity, CreateTeam request, Map<String, String> authHeaders) {
validateCreatedEntity(updatedEntity, request, authHeaders);
}
@Override
protected void validateDeletedEntity(
Object create, Team teamBeforeDeletion, Team teamAfterDeletion, Map<String, String> authHeaders)
CreateTeam create, Team teamBeforeDeletion, Team teamAfterDeletion, Map<String, String> authHeaders)
throws HttpResponseException {
super.validateDeletedEntity(create, teamBeforeDeletion, teamAfterDeletion, authHeaders);

View File

@ -25,11 +25,10 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.openmetadata.catalog.resources.teams.RoleResourceTest.createRole;
import static org.openmetadata.catalog.resources.teams.TeamResourceTest.createTeam;
import static org.openmetadata.catalog.security.SecurityUtil.authHeaders;
import static org.openmetadata.catalog.util.TestUtils.ADMIN_AUTH_HEADERS;
import static org.openmetadata.catalog.util.TestUtils.TEST_AUTH_HEADERS;
import static org.openmetadata.catalog.util.TestUtils.UpdateType.MINOR_UPDATE;
import static org.openmetadata.catalog.util.TestUtils.adminAuthHeaders;
import static org.openmetadata.catalog.util.TestUtils.assertListNotNull;
import static org.openmetadata.catalog.util.TestUtils.assertListNull;
import static org.openmetadata.catalog.util.TestUtils.assertResponse;
@ -37,7 +36,6 @@ import static org.openmetadata.catalog.util.TestUtils.assertResponse;
import com.fasterxml.jackson.core.JsonProcessingException;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@ -60,7 +58,7 @@ import org.openmetadata.catalog.entity.teams.Role;
import org.openmetadata.catalog.entity.teams.Team;
import org.openmetadata.catalog.entity.teams.User;
import org.openmetadata.catalog.exception.CatalogExceptionMessage;
import org.openmetadata.catalog.jdbi3.RoleRepository;
import org.openmetadata.catalog.jdbi3.RoleRepository.RoleEntityInterface;
import org.openmetadata.catalog.jdbi3.TeamRepository.TeamEntityInterface;
import org.openmetadata.catalog.jdbi3.UserRepository.UserEntityInterface;
import org.openmetadata.catalog.resources.EntityResourceTest;
@ -80,7 +78,7 @@ import org.openmetadata.catalog.util.TestUtils;
import org.openmetadata.catalog.util.TestUtils.UpdateType;
@Slf4j
public class UserResourceTest extends EntityResourceTest<User> {
public class UserResourceTest extends EntityResourceTest<User, CreateUser> {
final Profile PROFILE = new Profile().withImages(new ImageList().withImage(URI.create("http://image.com")));
public UserResourceTest() {
@ -90,26 +88,27 @@ public class UserResourceTest extends EntityResourceTest<User> {
@Test
void post_userWithoutEmail_400_badRequest(TestInfo test) {
// Create user with mandatory email field null
CreateUser create = create(test).withEmail(null);
CreateUser create = createRequest(test).withEmail(null);
HttpResponseException exception =
assertThrows(HttpResponseException.class, () -> createUser(create, adminAuthHeaders()));
assertThrows(HttpResponseException.class, () -> createEntity(create, ADMIN_AUTH_HEADERS));
assertResponse(exception, BAD_REQUEST, "[email must not be null]");
// Create user with mandatory email field empty
create.withEmail("");
exception = assertThrows(HttpResponseException.class, () -> createUser(create, adminAuthHeaders()));
exception = assertThrows(HttpResponseException.class, () -> createEntity(create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponseContains(exception, BAD_REQUEST, "email must match \"^\\S+@\\S+\\.\\S+$\"");
TestUtils.assertResponseContains(exception, BAD_REQUEST, "email size must be between 6 and 127");
// Create user with mandatory email field with invalid email address
create.withEmail("invalidEmail");
exception = assertThrows(HttpResponseException.class, () -> createUser(create, adminAuthHeaders()));
exception = assertThrows(HttpResponseException.class, () -> createEntity(create, ADMIN_AUTH_HEADERS));
TestUtils.assertResponseContains(exception, BAD_REQUEST, "[email must match \"^\\S+@\\S+\\.\\S+$\"]");
}
@Test
void post_validUser_200_ok_without_login(TestInfo test) {
CreateUser create = create(test, 6).withDisplayName("displayName").withEmail("test@email.com").withIsAdmin(true);
CreateUser create =
createRequest(test, 6).withDisplayName("displayName").withEmail("test@email.com").withIsAdmin(true);
HttpResponseException exception =
assertThrows(HttpResponseException.class, () -> createAndCheckEntity(create, null));
@ -119,27 +118,27 @@ public class UserResourceTest extends EntityResourceTest<User> {
@Test
void post_validUser_200_ok(TestInfo test) throws IOException {
// Create user with different optional fields
CreateUser create = create(test, 1);
createAndCheckEntity(create, adminAuthHeaders());
CreateUser create = createRequest(test, 1);
createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
create = create(test, 2).withDisplayName("displayName");
createAndCheckEntity(create, adminAuthHeaders());
create = createRequest(test, 2).withDisplayName("displayName");
createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
create = create(test, 3).withProfile(PROFILE);
createAndCheckEntity(create, adminAuthHeaders());
create = createRequest(test, 3).withProfile(PROFILE);
createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
create = create(test, 5).withDisplayName("displayName").withProfile(PROFILE).withIsBot(true);
createAndCheckEntity(create, adminAuthHeaders());
create = createRequest(test, 5).withDisplayName("displayName").withProfile(PROFILE).withIsBot(true);
createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
create = create(test, 6).withDisplayName("displayName").withProfile(PROFILE).withIsAdmin(true);
createAndCheckEntity(create, adminAuthHeaders());
create = createRequest(test, 6).withDisplayName("displayName").withProfile(PROFILE).withIsAdmin(true);
createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
}
@Test
void put_validUser_200_ok(TestInfo test) throws IOException {
// Create user with different optional fields
CreateUser create = create(test, 1);
User user = updateAndCheckEntity(create, CREATED, adminAuthHeaders(), UpdateType.CREATED, null);
CreateUser create = createRequest(test, 1);
User user = updateAndCheckEntity(create, CREATED, ADMIN_AUTH_HEADERS, UpdateType.CREATED, null);
// Update the user information using PUT
String oldEmail = create.getEmail();
@ -153,41 +152,48 @@ public class UserResourceTest extends EntityResourceTest<User> {
change
.getFieldsUpdated()
.add(new FieldChange().withName("email").withOldValue(oldEmail).withNewValue("test1@email.com"));
updateAndCheckEntity(update, OK, adminAuthHeaders(), MINOR_UPDATE, change);
updateAndCheckEntity(update, OK, ADMIN_AUTH_HEADERS, MINOR_UPDATE, change);
}
@Test
void post_validAdminUser_Non_Admin_401(TestInfo test) {
CreateUser create =
create(test, 6).withName("test").withDisplayName("displayName").withEmail("test@email.com").withIsAdmin(true);
createRequest(test, 6)
.withName("test")
.withDisplayName("displayName")
.withEmail("test@email.com")
.withIsAdmin(true);
HttpResponseException exception =
assertThrows(
HttpResponseException.class, () -> createAndCheckEntity(create, authHeaders("test@open-metadata.org")));
assertThrows(HttpResponseException.class, () -> createAndCheckEntity(create, TEST_AUTH_HEADERS));
assertResponse(exception, FORBIDDEN, "Principal: CatalogPrincipal{name='test'} is not admin");
}
@Test
void post_validAdminUser_200_ok(TestInfo test) throws IOException {
CreateUser create =
create(test, 6).withName("test1").withDisplayName("displayName").withEmail("test1@email.com").withIsAdmin(true);
createAndCheckEntity(create, adminAuthHeaders());
createRequest(test, 6)
.withName("test1")
.withDisplayName("displayName")
.withEmail("test1@email.com")
.withIsAdmin(true);
createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
}
@Test
void post_validUserWithTeams_200_ok(TestInfo test) throws IOException {
// Create user with different optional fields
TeamResourceTest teamResourceTest = new TeamResourceTest();
Team team1 = createTeam(teamResourceTest.create(test, 1), adminAuthHeaders());
Team team2 = createTeam(teamResourceTest.create(test, 2), adminAuthHeaders());
Team team1 = teamResourceTest.createEntity(teamResourceTest.createRequest(test, 1), ADMIN_AUTH_HEADERS);
Team team2 = teamResourceTest.createEntity(teamResourceTest.createRequest(test, 2), ADMIN_AUTH_HEADERS);
List<UUID> teams = Arrays.asList(team1.getId(), team2.getId());
CreateUser create = create(test).withTeams(teams);
User user = createAndCheckEntity(create, adminAuthHeaders());
CreateUser create = createRequest(test).withTeams(teams);
User user = createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
// Ensure Team has relationship to this user
team1 = TeamResourceTest.getTeam(team1.getId(), "users", adminAuthHeaders());
team1 = teamResourceTest.getEntity(team1.getId(), "users", ADMIN_AUTH_HEADERS);
assertEquals(user.getId(), team1.getUsers().get(0).getId());
team2 = TeamResourceTest.getTeam(team2.getId(), "users", adminAuthHeaders());
team2 = teamResourceTest.getEntity(team2.getId(), "users", ADMIN_AUTH_HEADERS);
assertEquals(user.getId(), team2.getUsers().get(0).getId());
}
@ -195,11 +201,11 @@ public class UserResourceTest extends EntityResourceTest<User> {
void post_validUserWithRoles_200_ok(TestInfo test) throws IOException {
// Create user with different optional fields
RoleResourceTest roleResourceTest = new RoleResourceTest();
Role role1 = createRole(roleResourceTest.create(test, 1), adminAuthHeaders());
Role role2 = createRole(roleResourceTest.create(test, 2), adminAuthHeaders());
Role role1 = roleResourceTest.createEntity(roleResourceTest.createRequest(test, 1), ADMIN_AUTH_HEADERS);
Role role2 = roleResourceTest.createEntity(roleResourceTest.createRequest(test, 2), ADMIN_AUTH_HEADERS);
List<UUID> roles = Arrays.asList(role1.getId(), role2.getId());
CreateUser create = create(test).withRoles(roles);
User user = createAndCheckEntity(create, adminAuthHeaders());
CreateUser create = createRequest(test).withRoles(roles);
User user = createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
// Ensure User has relationship to these roles
String[] expectedRoles = roles.stream().map(UUID::toString).sorted().toArray(String[]::new);
@ -211,20 +217,20 @@ public class UserResourceTest extends EntityResourceTest<User> {
@Test
void get_listUsersWithTeams_200_ok(TestInfo test) throws IOException {
TeamResourceTest teamResourceTest = new TeamResourceTest();
Team team1 = createTeam(teamResourceTest.create(test, 1), adminAuthHeaders());
Team team2 = createTeam(teamResourceTest.create(test, 2), adminAuthHeaders());
Team team1 = teamResourceTest.createEntity(teamResourceTest.createRequest(test, 1), ADMIN_AUTH_HEADERS);
Team team2 = teamResourceTest.createEntity(teamResourceTest.createRequest(test, 2), ADMIN_AUTH_HEADERS);
List<UUID> teams = List.of(team1.getId(), team2.getId());
List<UUID> team = List.of(team1.getId());
// user0 is part of no teams
// user1 is part of team1
// user2 is part of team1, and team2
CreateUser create = create(test, 0);
User user0 = createAndCheckEntity(create, adminAuthHeaders());
create = create(test, 1).withTeams(team);
User user1 = createAndCheckEntity(create, adminAuthHeaders());
create = create(test, 2).withTeams(teams);
User user2 = createAndCheckEntity(create, adminAuthHeaders());
CreateUser create = createRequest(test, 0);
User user0 = createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
create = createRequest(test, 1).withTeams(team);
User user1 = createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
create = createRequest(test, 2).withTeams(teams);
User user2 = createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
Predicate<User> isUser0 = u -> u.getId().equals(user0.getId());
Predicate<User> isUser1 = u -> u.getId().equals(user1.getId());
@ -236,7 +242,7 @@ public class UserResourceTest extends EntityResourceTest<User> {
put("team", team1.getName());
}
};
ResultList<User> users = listEntities(queryParams, 100_000, null, null, adminAuthHeaders());
ResultList<User> users = listEntities(queryParams, 100_000, null, null, ADMIN_AUTH_HEADERS);
assertEquals(2, users.getData().size());
assertTrue(users.getData().stream().anyMatch(isUser1));
assertTrue(users.getData().stream().anyMatch(isUser2));
@ -247,11 +253,11 @@ public class UserResourceTest extends EntityResourceTest<User> {
put("team", team2.getName());
}
};
users = listEntities(queryParams, 100_000, null, null, adminAuthHeaders());
users = listEntities(queryParams, 100_000, null, null, ADMIN_AUTH_HEADERS);
assertEquals(1, users.getData().size());
assertTrue(users.getData().stream().anyMatch(isUser2));
users = listEntities(null, 100_000, null, null, adminAuthHeaders());
users = listEntities(null, 100_000, null, null, ADMIN_AUTH_HEADERS);
assertTrue(users.getData().stream().anyMatch(isUser0));
assertTrue(users.getData().stream().anyMatch(isUser1));
assertTrue(users.getData().stream().anyMatch(isUser2));
@ -259,30 +265,30 @@ public class UserResourceTest extends EntityResourceTest<User> {
@Test
void get_userWithInvalidFields_400_BadRequest(TestInfo test) throws HttpResponseException {
User user = createUser(create(test), adminAuthHeaders());
User user = createEntity(createRequest(test), ADMIN_AUTH_HEADERS);
// Empty query field .../users?fields=
HttpResponseException exception =
assertThrows(HttpResponseException.class, () -> getEntity(user.getId(), "test", adminAuthHeaders()));
assertThrows(HttpResponseException.class, () -> getEntity(user.getId(), "test", ADMIN_AUTH_HEADERS));
TestUtils.assertResponseContains(exception, BAD_REQUEST, "Invalid field name");
// .../users?fields=invalidField
exception =
assertThrows(HttpResponseException.class, () -> getEntity(user.getId(), "invalidField", adminAuthHeaders()));
assertThrows(HttpResponseException.class, () -> getEntity(user.getId(), "invalidField", ADMIN_AUTH_HEADERS));
assertResponse(exception, BAD_REQUEST, CatalogExceptionMessage.invalidField("invalidField"));
}
/**
* @see EntityResourceTest#put_addDeleteFollower_200 test for tests related to GET user with owns field parameter
* @see EntityResourceTest#put_addDeleteFollower_200 for tests related getting user with follows list
* @see EntityResourceTest put_addDeleteFollower_200 test for tests related to GET user with owns field parameter
* @see EntityResourceTest put_addDeleteFollower_200 for tests related getting user with follows list
* @see TableResourceTest also tests GET user returns owns list
*/
@Test
void patch_userNameChange_as_another_user_401(TestInfo test) throws HttpResponseException, JsonProcessingException {
// Ensure username can't be changed using patch
User user =
createUser(
create(test, 7).withName("test23").withDisplayName("displayName").withEmail("test23@email.com"),
createEntity(
createRequest(test, 7).withName("test23").withDisplayName("displayName").withEmail("test23@email.com"),
authHeaders("test23@email.com"));
String userJson = JsonUtils.pojoToJson(user);
user.setDisplayName("newName");
@ -295,8 +301,8 @@ public class UserResourceTest extends EntityResourceTest<User> {
void patch_makeAdmin_as_another_user_401(TestInfo test) throws HttpResponseException, JsonProcessingException {
// Ensure username can't be changed using patch
User user =
createUser(
create(test, 6).withName("test2").withDisplayName("displayName").withEmail("test2@email.com"),
createEntity(
createRequest(test, 6).withName("test2").withDisplayName("displayName").withEmail("test2@email.com"),
authHeaders("test2@email.com"));
String userJson = JsonUtils.pojoToJson(user);
user.setIsAdmin(Boolean.TRUE);
@ -309,33 +315,36 @@ public class UserResourceTest extends EntityResourceTest<User> {
void patch_userNameChange_as_same_user_200_ok(TestInfo test) throws HttpResponseException, JsonProcessingException {
// Ensure username can't be changed using patch
User user =
createUser(
create(test, 6).withName("test").withDisplayName("displayName").withEmail("test@email.com"),
createEntity(
createRequest(test, 6).withName("test").withDisplayName("displayName").withEmail("test@email.com"),
authHeaders("test@email.com"));
String userJson = JsonUtils.pojoToJson(user);
String newDisplayName = "newDisplayName";
user.setDisplayName(newDisplayName); // Update the name
user = patchUser(userJson, user, adminAuthHeaders()); // Patch the user
user = patchUser(userJson, user, ADMIN_AUTH_HEADERS); // Patch the user
assertEquals(newDisplayName, user.getDisplayName());
}
@Test
void patch_userAttributes_as_admin_200_ok(TestInfo test) throws IOException {
// Create user without any attributes - ***Note*** isAdmin by default is false.
User user = createUser(create(test), adminAuthHeaders());
User user = createEntity(createRequest(test).withProfile(null), ADMIN_AUTH_HEADERS);
assertListNull(user.getDisplayName(), user.getIsBot(), user.getProfile(), user.getTimezone());
TeamResourceTest teamResourceTest = new TeamResourceTest();
EntityReference team1 =
new TeamEntityInterface(createTeam(teamResourceTest.create(test, 1), adminAuthHeaders()))
new TeamEntityInterface(
teamResourceTest.createEntity(teamResourceTest.createRequest(test, 1), ADMIN_AUTH_HEADERS))
.getEntityReference()
.withHref(null);
EntityReference team2 =
new TeamEntityInterface(createTeam(teamResourceTest.create(test, 2), adminAuthHeaders()))
new TeamEntityInterface(
teamResourceTest.createEntity(teamResourceTest.createRequest(test, 2), ADMIN_AUTH_HEADERS))
.getEntityReference()
.withHref(null);
EntityReference team3 =
new TeamEntityInterface(createTeam(teamResourceTest.create(test, 3), adminAuthHeaders()))
new TeamEntityInterface(
teamResourceTest.createEntity(teamResourceTest.createRequest(test, 3), ADMIN_AUTH_HEADERS))
.getEntityReference()
.withHref(null);
List<EntityReference> teams = Arrays.asList(team1, team2);
@ -343,7 +352,8 @@ public class UserResourceTest extends EntityResourceTest<User> {
RoleResourceTest roleResourceTest = new RoleResourceTest();
EntityReference role1 =
new RoleRepository.RoleEntityInterface(createRole(roleResourceTest.create(test, 1), adminAuthHeaders()))
new RoleEntityInterface(
roleResourceTest.createEntity(roleResourceTest.createRequest(test, 1), ADMIN_AUTH_HEADERS))
.getEntityReference()
.withHref(null);
List<EntityReference> roles1 = Arrays.asList(role1);
@ -369,7 +379,7 @@ public class UserResourceTest extends EntityResourceTest<User> {
change.getFieldsAdded().add(new FieldChange().withName("displayName").withNewValue("displayName"));
change.getFieldsAdded().add(new FieldChange().withName("profile").withNewValue(profile));
change.getFieldsAdded().add(new FieldChange().withName("isBot").withNewValue(false));
user = patchEntityAndCheck(user, origJson, adminAuthHeaders(), MINOR_UPDATE, change);
user = patchEntityAndCheck(user, origJson, ADMIN_AUTH_HEADERS, MINOR_UPDATE, change);
//
// Replace the attributes
@ -379,7 +389,8 @@ public class UserResourceTest extends EntityResourceTest<User> {
Profile profile1 = new Profile().withImages(new ImageList().withImage(URI.create("http://image2.com")));
EntityReference role2 =
new RoleRepository.RoleEntityInterface(createRole(roleResourceTest.create(test, 2), adminAuthHeaders()))
new RoleEntityInterface(
roleResourceTest.createEntity(roleResourceTest.createRequest(test, 2), ADMIN_AUTH_HEADERS))
.getEntityReference()
.withHref(null);
List<EntityReference> roles2 = Arrays.asList(role2);
@ -407,7 +418,7 @@ public class UserResourceTest extends EntityResourceTest<User> {
change.getFieldsUpdated().add(new FieldChange().withName("profile").withOldValue(profile).withNewValue(profile1));
change.getFieldsUpdated().add(new FieldChange().withName("isBot").withOldValue(false).withNewValue(true));
user = patchEntityAndCheck(user, origJson, adminAuthHeaders(), MINOR_UPDATE, change);
user = patchEntityAndCheck(user, origJson, ADMIN_AUTH_HEADERS, MINOR_UPDATE, change);
//
// Remove the attributes
@ -429,36 +440,37 @@ public class UserResourceTest extends EntityResourceTest<User> {
change.getFieldsDeleted().add(new FieldChange().withName("displayName").withOldValue("displayName1"));
change.getFieldsDeleted().add(new FieldChange().withName("profile").withOldValue(profile1));
change.getFieldsDeleted().add(new FieldChange().withName("isBot").withOldValue(true).withNewValue(null));
patchEntityAndCheck(user, origJson, adminAuthHeaders(), MINOR_UPDATE, change);
patchEntityAndCheck(user, origJson, ADMIN_AUTH_HEADERS, MINOR_UPDATE, change);
}
@Test
void delete_validUser_as_admin_200(TestInfo test) throws IOException {
TeamResourceTest teamResourceTest = new TeamResourceTest();
Team team = createTeam(teamResourceTest.create(test), adminAuthHeaders());
Team team = teamResourceTest.createEntity(teamResourceTest.createRequest(test), ADMIN_AUTH_HEADERS);
List<UUID> teamIds = Collections.singletonList(team.getId());
CreateUser create = create(test).withProfile(PROFILE).withTeams(teamIds);
User user = createUser(create, adminAuthHeaders());
// Create user with teams
CreateUser create = createRequest(test).withProfile(PROFILE).withTeams(teamIds);
User user = createEntity(create, ADMIN_AUTH_HEADERS);
// Add user as follower to a table
TableResourceTest tableResourceTest = new TableResourceTest();
Table table = tableResourceTest.createEntity(test, 1);
tableResourceTest.addAndCheckFollower(table.getId(), user.getId(), CREATED, 1, adminAuthHeaders());
tableResourceTest.addAndCheckFollower(table.getId(), user.getId(), CREATED, 1, ADMIN_AUTH_HEADERS);
// Delete user
deleteAndCheckEntity(user, adminAuthHeaders());
deleteAndCheckEntity(user, ADMIN_AUTH_HEADERS);
// Make sure the user is no longer following the table
team = TeamResourceTest.getTeam(team.getId(), "users", adminAuthHeaders());
team = teamResourceTest.getEntity(team.getId(), "users", ADMIN_AUTH_HEADERS);
assertTrue(team.getUsers().isEmpty());
tableResourceTest.checkFollowerDeleted(table.getId(), user.getId(), adminAuthHeaders());
tableResourceTest.checkFollowerDeleted(table.getId(), user.getId(), ADMIN_AUTH_HEADERS);
// User can no longer follow other entities
HttpResponseException exception =
assertThrows(
HttpResponseException.class,
() -> tableResourceTest.addAndCheckFollower(table.getId(), user.getId(), CREATED, 1, adminAuthHeaders()));
() -> tableResourceTest.addAndCheckFollower(table.getId(), user.getId(), CREATED, 1, ADMIN_AUTH_HEADERS));
assertResponse(exception, NOT_FOUND, CatalogExceptionMessage.entityNotFound("user", user.getId()));
// TODO deactivated user can't be made owner
@ -476,25 +488,6 @@ public class UserResourceTest extends EntityResourceTest<User> {
return patchUser(updated.getId(), originalJson, updated, headers);
}
public CreateUser create(TestInfo test) {
return create(getEntityName(test));
}
public CreateUser create(TestInfo test, int index) {
return create(getEntityName(test, index));
}
public static CreateUser create(String name) {
// user part of the email should be less than 64 in length
String emailUser = name == null || name.isEmpty() ? UUID.randomUUID().toString() : name;
emailUser = emailUser.length() > 64 ? emailUser.substring(0, 64) : emailUser;
return new CreateUser().withName(name).withEmail(emailUser + "@open-metadata.org");
}
public static User createUser(CreateUser create, Map<String, String> authHeaders) throws HttpResponseException {
return TestUtils.post(CatalogApplicationTest.getResource("users"), create, User.class, authHeaders);
}
/** Validate returned fields GET .../users/{id}?fields="..." or GET .../users/name/{name}?fields="..." */
@Override
public void validateGetWithDifferentFields(User user, boolean byName) throws HttpResponseException {
@ -502,8 +495,8 @@ public class UserResourceTest extends EntityResourceTest<User> {
String fields = "profile";
user =
byName
? getEntityByName(user.getName(), null, fields, adminAuthHeaders())
: getEntity(user.getId(), fields, adminAuthHeaders());
? getEntityByName(user.getName(), fields, ADMIN_AUTH_HEADERS)
: getEntity(user.getId(), fields, ADMIN_AUTH_HEADERS);
assertNotNull(user.getProfile());
assertNull(user.getTeams());
@ -511,19 +504,22 @@ public class UserResourceTest extends EntityResourceTest<User> {
fields = "profile, teams";
user =
byName
? getEntityByName(user.getName(), null, fields, adminAuthHeaders())
: getEntity(user.getId(), fields, adminAuthHeaders());
? getEntityByName(user.getName(), fields, ADMIN_AUTH_HEADERS)
: getEntity(user.getId(), fields, ADMIN_AUTH_HEADERS);
assertListNotNull(user.getProfile(), user.getTeams());
}
@Override
public Object createRequest(String name, String description, String displayName, EntityReference owner) {
return create(name)
public CreateUser createRequest(String name, String description, String displayName, EntityReference owner) {
// user part of the email should be less than 64 in length
String emailUser = name == null || name.isEmpty() ? UUID.randomUUID().toString() : name;
emailUser = emailUser.length() > 64 ? emailUser.substring(0, 64) : emailUser;
return new CreateUser()
.withName(name)
.withEmail(emailUser + "@open-metadata.org")
.withDescription(description)
.withDisplayName(displayName)
.withProfile(PROFILE)
.withTeams(List.of(TEAM1.getId()))
.withRoles(List.of(ROLE1.getId()));
.withProfile(PROFILE);
}
@Override
@ -531,15 +527,15 @@ public class UserResourceTest extends EntityResourceTest<User> {
LocationResourceTest locationResourceTest = new LocationResourceTest();
EntityReference userRef = new EntityReference().withId(user.getId()).withType("user");
locationResourceTest.createEntity(
locationResourceTest.createRequest(getEntityName(test, 0), null, null, userRef), adminAuthHeaders());
locationResourceTest.createRequest(getEntityName(test, 0), null, null, userRef), ADMIN_AUTH_HEADERS);
locationResourceTest.createEntity(
locationResourceTest.createRequest(getEntityName(test, 1), null, null, TEAM_OWNER1), adminAuthHeaders());
locationResourceTest.createRequest(getEntityName(test, 1), null, null, TEAM_OWNER1), ADMIN_AUTH_HEADERS);
return user;
}
@Override
protected void validateDeletedEntity(
Object create, User userBeforeDeletion, User userAfterDeletion, Map<String, String> authHeaders)
CreateUser create, User userBeforeDeletion, User userAfterDeletion, Map<String, String> authHeaders)
throws HttpResponseException {
super.validateDeletedEntity(create, userBeforeDeletion, userAfterDeletion, authHeaders);
@ -556,13 +552,7 @@ public class UserResourceTest extends EntityResourceTest<User> {
}
@Override
public EntityReference getContainer(Object createRequest) throws URISyntaxException {
return null; // No container entity
}
@Override
public void validateCreatedEntity(User user, Object request, Map<String, String> authHeaders) {
CreateUser createRequest = (CreateUser) request;
public void validateCreatedEntity(User user, CreateUser createRequest, Map<String, String> authHeaders) {
validateCommonEntityFields(
getEntityInterface(user), createRequest.getDescription(), TestUtils.getPrincipal(authHeaders), null);
@ -599,7 +589,7 @@ public class UserResourceTest extends EntityResourceTest<User> {
}
@Override
public void validateUpdatedEntity(User user, Object request, Map<String, String> authHeaders) {
public void validateUpdatedEntity(User user, CreateUser request, Map<String, String> authHeaders) {
validateCreatedEntity(user, request, authHeaders);
}
@ -649,6 +639,7 @@ public class UserResourceTest extends EntityResourceTest<User> {
Profile actualProfile = JsonUtils.readValue(actual.toString(), Profile.class);
assertEquals(expectedProfile, actualProfile);
} else if (fieldName.equals("teams") || fieldName.equals("roles")) {
@SuppressWarnings("unchecked")
List<EntityReference> expectedList = (List<EntityReference>) expected;
List<EntityReference> actualList = JsonUtils.readObjects(actual.toString(), EntityReference.class);
assertEquals(expectedList, actualList);

View File

@ -17,13 +17,12 @@ import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
import static javax.ws.rs.core.Response.Status.FORBIDDEN;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.openmetadata.catalog.security.SecurityUtil.authHeaders;
import static org.openmetadata.catalog.util.TestUtils.adminAuthHeaders;
import static org.openmetadata.catalog.util.TestUtils.ADMIN_AUTH_HEADERS;
import static org.openmetadata.catalog.util.TestUtils.TEST_AUTH_HEADERS;
import static org.openmetadata.catalog.util.TestUtils.assertListNotNull;
import static org.openmetadata.catalog.util.TestUtils.assertResponse;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -52,7 +51,7 @@ import org.openmetadata.catalog.util.TestUtils;
import org.openmetadata.catalog.util.TestUtils.UpdateType;
@Slf4j
public class TopicResourceTest extends EntityResourceTest<Topic> {
public class TopicResourceTest extends EntityResourceTest<Topic, CreateTopic> {
public TopicResourceTest() {
super(Entity.TOPIC, Topic.class, TopicList.class, "topics", TopicResource.FIELDS, true, true, true, true);
@ -61,30 +60,30 @@ public class TopicResourceTest extends EntityResourceTest<Topic> {
@Test
void post_validTopics_as_admin_200_OK(TestInfo test) throws IOException {
// Create team with different optional fields
CreateTopic create = create(test);
createAndCheckEntity(create, adminAuthHeaders());
CreateTopic create = createRequest(test);
createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
create.withName(getEntityName(test, 1)).withDescription("description");
Topic topic = createAndCheckEntity(create, adminAuthHeaders());
Topic topic = createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
String expectedFQN = KAFKA_REFERENCE.getName() + "." + topic.getName();
assertEquals(expectedFQN, topic.getFullyQualifiedName());
}
@Test
void post_topicWithUserOwner_200_ok(TestInfo test) throws IOException {
createAndCheckEntity(create(test).withOwner(USER_OWNER1), adminAuthHeaders());
createAndCheckEntity(createRequest(test).withOwner(USER_OWNER1), ADMIN_AUTH_HEADERS);
}
@Test
void post_topicWithTeamOwner_200_ok(TestInfo test) throws IOException {
createAndCheckEntity(create(test).withOwner(TEAM_OWNER1), adminAuthHeaders());
createAndCheckEntity(createRequest(test).withOwner(TEAM_OWNER1), ADMIN_AUTH_HEADERS);
}
@Test
void post_topic_as_non_admin_401(TestInfo test) {
CreateTopic create = create(test);
CreateTopic create = createRequest(test);
HttpResponseException exception =
assertThrows(HttpResponseException.class, () -> createTopic(create, authHeaders("test@open-metadata.org")));
assertThrows(HttpResponseException.class, () -> createEntity(create, TEST_AUTH_HEADERS));
assertResponse(exception, FORBIDDEN, "Principal: CatalogPrincipal{name='test'} is not admin");
}
@ -93,19 +92,20 @@ public class TopicResourceTest extends EntityResourceTest<Topic> {
// Service is required field
HttpResponseException exception =
assertThrows(
HttpResponseException.class, () -> createTopic(create(test).withService(null), adminAuthHeaders()));
HttpResponseException.class, () -> createEntity(createRequest(test).withService(null), ADMIN_AUTH_HEADERS));
assertResponse(exception, BAD_REQUEST, "[service must not be null]");
// Partitions is required field
exception =
assertThrows(
HttpResponseException.class, () -> createTopic(create(test).withPartitions(null), adminAuthHeaders()));
HttpResponseException.class,
() -> createEntity(createRequest(test).withPartitions(null), ADMIN_AUTH_HEADERS));
assertResponse(exception, BAD_REQUEST, "[partitions must not be null]");
// Partitions must be >= 1
exception =
assertThrows(
HttpResponseException.class, () -> createTopic(create(test).withPartitions(0), adminAuthHeaders()));
HttpResponseException.class, () -> createEntity(createRequest(test).withPartitions(0), ADMIN_AUTH_HEADERS));
assertResponse(exception, BAD_REQUEST, "[partitions must be greater than or equal to 1]");
}
@ -115,7 +115,7 @@ public class TopicResourceTest extends EntityResourceTest<Topic> {
// Create topic for each service and test APIs
for (EntityReference service : differentServices) {
createAndCheckEntity(create(test).withService(service), adminAuthHeaders());
createAndCheckEntity(createRequest(test).withService(service), ADMIN_AUTH_HEADERS);
// List topics by filtering on service name and ensure right topics in the response
Map<String, String> queryParams =
@ -124,7 +124,7 @@ public class TopicResourceTest extends EntityResourceTest<Topic> {
put("service", service.getName());
}
};
ResultList<Topic> list = listEntities(queryParams, adminAuthHeaders());
ResultList<Topic> list = listEntities(queryParams, ADMIN_AUTH_HEADERS);
for (Topic topic : list.getData()) {
assertEquals(service.getName(), topic.getService().getName());
}
@ -134,7 +134,7 @@ public class TopicResourceTest extends EntityResourceTest<Topic> {
@Test
void put_topicAttributes_200_ok(TestInfo test) throws IOException {
CreateTopic createTopic =
create(test)
createRequest(test)
.withOwner(USER_OWNER1)
.withMaximumMessageSize(1)
.withMinimumInSyncReplicas(1)
@ -147,7 +147,7 @@ public class TopicResourceTest extends EntityResourceTest<Topic> {
.withCleanupPolicies(List.of(CleanupPolicy.COMPACT));
// Patch and update the topic
Topic topic = createEntity(createTopic, adminAuthHeaders());
Topic topic = createEntity(createTopic, ADMIN_AUTH_HEADERS);
createTopic
.withOwner(TEAM_OWNER1)
.withMinimumInSyncReplicas(2)
@ -181,13 +181,13 @@ public class TopicResourceTest extends EntityResourceTest<Topic> {
.getFieldsAdded()
.add(new FieldChange().withName("cleanupPolicies").withNewValue(List.of(CleanupPolicy.DELETE)));
updateAndCheckEntity(createTopic, Status.OK, adminAuthHeaders(), UpdateType.MINOR_UPDATE, change);
updateAndCheckEntity(createTopic, Status.OK, ADMIN_AUTH_HEADERS, UpdateType.MINOR_UPDATE, change);
}
@Test
void patch_topicAttributes_200_ok(TestInfo test) throws IOException {
CreateTopic createTopic =
create(test)
createRequest(test)
.withOwner(USER_OWNER1)
.withMaximumMessageSize(1)
.withMinimumInSyncReplicas(1)
@ -200,7 +200,7 @@ public class TopicResourceTest extends EntityResourceTest<Topic> {
.withCleanupPolicies(List.of(CleanupPolicy.COMPACT));
// Patch and update the topic
Topic topic = createEntity(createTopic, adminAuthHeaders());
Topic topic = createEntity(createTopic, ADMIN_AUTH_HEADERS);
topic.setHref(null);
topic.getOwner().withHref(null);
String origJson = JsonUtils.pojoToJson(topic);
@ -237,7 +237,7 @@ public class TopicResourceTest extends EntityResourceTest<Topic> {
change
.getFieldsAdded()
.add(new FieldChange().withName("cleanupPolicies").withNewValue(List.of(CleanupPolicy.DELETE)));
patchEntityAndCheck(topic, origJson, adminAuthHeaders(), UpdateType.MINOR_UPDATE, change);
patchEntityAndCheck(topic, origJson, ADMIN_AUTH_HEADERS, UpdateType.MINOR_UPDATE, change);
}
@Test
@ -245,10 +245,6 @@ public class TopicResourceTest extends EntityResourceTest<Topic> {
// TODO
}
public static Topic createTopic(CreateTopic create, Map<String, String> authHeaders) throws HttpResponseException {
return TestUtils.post(getResource("topics"), create, Topic.class, authHeaders);
}
/** Validate returned fields GET .../topics/{id}?fields="..." or GET .../topics/name/{fqn}?fields="..." */
@Override
public void validateGetWithDifferentFields(Topic topic, boolean byName) throws HttpResponseException {
@ -256,8 +252,8 @@ public class TopicResourceTest extends EntityResourceTest<Topic> {
String fields = "owner";
topic =
byName
? getTopicByName(topic.getFullyQualifiedName(), fields, adminAuthHeaders())
: getTopic(topic.getId(), fields, adminAuthHeaders());
? getTopicByName(topic.getFullyQualifiedName(), fields, ADMIN_AUTH_HEADERS)
: getTopic(topic.getId(), fields, ADMIN_AUTH_HEADERS);
assertListNotNull(topic.getOwner(), topic.getService(), topic.getServiceType());
}
@ -274,29 +270,24 @@ public class TopicResourceTest extends EntityResourceTest<Topic> {
return TestUtils.get(target, Topic.class, authHeaders);
}
private CreateTopic create(TestInfo test) {
return create(getEntityName(test));
}
private CreateTopic create(String name) {
return new CreateTopic().withName(name).withService(KAFKA_REFERENCE).withPartitions(1);
}
@Override
public CreateTopic createRequest(String name, String description, String displayName, EntityReference owner) {
return create(name).withDescription(description).withOwner(owner);
return new CreateTopic()
.withName(name)
.withService(KAFKA_REFERENCE)
.withPartitions(1)
.withDescription(description)
.withOwner(owner);
}
@Override
public EntityReference getContainer(Object createRequest) throws URISyntaxException {
CreateTopic createTopic = (CreateTopic) createRequest;
return createTopic.getService();
public EntityReference getContainer(CreateTopic createRequest) {
return createRequest.getService();
}
@Override
public void validateCreatedEntity(Topic topic, Object request, Map<String, String> authHeaders)
public void validateCreatedEntity(Topic topic, CreateTopic createRequest, Map<String, String> authHeaders)
throws HttpResponseException {
CreateTopic createRequest = (CreateTopic) request;
validateCommonEntityFields(
getEntityInterface(topic),
createRequest.getDescription(),
@ -308,7 +299,7 @@ public class TopicResourceTest extends EntityResourceTest<Topic> {
}
@Override
public void validateUpdatedEntity(Topic topic, Object request, Map<String, String> authHeaders)
public void validateUpdatedEntity(Topic topic, CreateTopic request, Map<String, String> authHeaders)
throws HttpResponseException {
validateCreatedEntity(topic, request, authHeaders);
}
@ -337,6 +328,7 @@ public class TopicResourceTest extends EntityResourceTest<Topic> {
return;
}
if (fieldName.equals("cleanupPolicies")) {
@SuppressWarnings("unchecked")
List<CleanupPolicy> expectedCleanupPolicies = (List<CleanupPolicy>) expected;
List<CleanupPolicy> actualCleanupPolicies = JsonUtils.readObjects(actual.toString(), CleanupPolicy.class);
assertEquals(expectedCleanupPolicies, actualCleanupPolicies);

View File

@ -18,8 +18,8 @@ import static javax.ws.rs.core.Response.Status.NOT_FOUND;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.openmetadata.catalog.Entity.TABLE;
import static org.openmetadata.catalog.util.TestUtils.ADMIN_AUTH_HEADERS;
import static org.openmetadata.catalog.util.TestUtils.NON_EXISTENT_ENTITY;
import static org.openmetadata.catalog.util.TestUtils.adminAuthHeaders;
import static org.openmetadata.catalog.util.TestUtils.assertResponse;
import static org.openmetadata.common.utils.CommonUtil.getDateStringByOffset;
@ -69,8 +69,8 @@ public class UsageResourceTest extends CatalogApplicationTest {
TableResourceTest tableResourceTest = new TableResourceTest();
tableResourceTest.setup(test); // Initialize TableResourceTest for using helper methods
for (int i = 0; i < TABLE_COUNT; i++) {
CreateTable createTable = tableResourceTest.create(test, i);
TABLES.add(tableResourceTest.createEntity(createTable, adminAuthHeaders()));
CreateTable createTable = tableResourceTest.createRequest(test, i);
TABLES.add(tableResourceTest.createEntity(createTable, ADMIN_AUTH_HEADERS));
}
}
@ -79,7 +79,7 @@ public class UsageResourceTest extends CatalogApplicationTest {
HttpResponseException exception =
assertThrows(
HttpResponseException.class,
() -> reportUsage(TABLE, NON_EXISTENT_ENTITY, usageReport(), adminAuthHeaders()));
() -> reportUsage(TABLE, NON_EXISTENT_ENTITY, usageReport(), ADMIN_AUTH_HEADERS));
assertResponse(exception, NOT_FOUND, CatalogExceptionMessage.entityNotFound(TABLE, NON_EXISTENT_ENTITY));
}
@ -89,7 +89,7 @@ public class UsageResourceTest extends CatalogApplicationTest {
HttpResponseException exception =
assertThrows(
HttpResponseException.class,
() -> reportUsage(invalidEntityType, UUID.randomUUID(), usageReport(), adminAuthHeaders()));
() -> reportUsage(invalidEntityType, UUID.randomUUID(), usageReport(), ADMIN_AUTH_HEADERS));
assertResponse(exception, NOT_FOUND, CatalogExceptionMessage.entityTypeNotFound(invalidEntityType));
}
@ -98,7 +98,7 @@ public class UsageResourceTest extends CatalogApplicationTest {
DailyCount dailyCount = usageReport().withCount(-1); // Negative usage count
HttpResponseException exception =
assertThrows(
HttpResponseException.class, () -> reportUsage(TABLE, UUID.randomUUID(), dailyCount, adminAuthHeaders()));
HttpResponseException.class, () -> reportUsage(TABLE, UUID.randomUUID(), dailyCount, ADMIN_AUTH_HEADERS));
assertResponse(exception, BAD_REQUEST, "[count must be greater than or equal to 0]");
}
@ -107,16 +107,16 @@ public class UsageResourceTest extends CatalogApplicationTest {
DailyCount usageReport = usageReport().withDate(null); // Negative usage count
HttpResponseException exception =
assertThrows(
HttpResponseException.class, () -> reportUsage(TABLE, UUID.randomUUID(), usageReport, adminAuthHeaders()));
HttpResponseException.class, () -> reportUsage(TABLE, UUID.randomUUID(), usageReport, ADMIN_AUTH_HEADERS));
assertResponse(exception, BAD_REQUEST, "[date must not be null]");
}
@Test
public void post_validUsageByName_200_OK(TestInfo test) throws HttpResponseException {
TableResourceTest tableResourceTest = new TableResourceTest();
Table table = tableResourceTest.createEntity(tableResourceTest.create(test), adminAuthHeaders());
Table table = tableResourceTest.createEntity(tableResourceTest.createRequest(test), ADMIN_AUTH_HEADERS);
DailyCount usageReport = usageReport().withCount(100).withDate(RestUtil.DATE_FORMAT.format(new Date()));
reportUsageByNameAndCheck(TABLE, table.getFullyQualifiedName(), usageReport, 100, 100, adminAuthHeaders());
reportUsageByNameAndCheck(TABLE, table.getFullyQualifiedName(), usageReport, 100, 100, ADMIN_AUTH_HEADERS);
}
@Order(1) // Run this method first before other usage records are created
@ -152,7 +152,7 @@ public class UsageResourceTest extends CatalogApplicationTest {
// Report usage
int weeklyCount = Math.min(day + 1, 7) * usageCount; // Expected cumulative weekly count
int monthlyCount = Math.min(day + 1, 30) * usageCount; // Expected cumulative monthly count
reportUsageAndCheck(TABLE, id, usageReport, weeklyCount, monthlyCount, adminAuthHeaders());
reportUsageAndCheck(TABLE, id, usageReport, weeklyCount, monthlyCount, ADMIN_AUTH_HEADERS);
// Database has cumulative count of all the table usage
databaseDailyCount += usageCount;
@ -173,18 +173,18 @@ public class UsageResourceTest extends CatalogApplicationTest {
databaseDailyCount,
databaseWeeklyCount,
databaseMonthlyCount,
adminAuthHeaders());
ADMIN_AUTH_HEADERS);
}
// Compute daily percentiles now that all table usage have been published for a given date
computePercentile(TABLE, date, adminAuthHeaders());
computePercentile(Entity.DATABASE, date, adminAuthHeaders());
computePercentile(TABLE, date, ADMIN_AUTH_HEADERS);
computePercentile(Entity.DATABASE, date, ADMIN_AUTH_HEADERS);
// TODO check database percentile
// For each day check percentile
for (int tableIndex = 0; tableIndex < TABLES.size(); tableIndex++) {
int expectedPercentile = 100 * (tableIndex) / TABLES.size();
EntityUsage usage = getUsage(TABLE, TABLES.get(tableIndex).getId(), date, 1, adminAuthHeaders());
EntityUsage usage = getUsage(TABLE, TABLES.get(tableIndex).getId(), date, 1, ADMIN_AUTH_HEADERS);
assertEquals(expectedPercentile, usage.getUsage().get(0).getDailyStats().getPercentileRank());
assertEquals(expectedPercentile, usage.getUsage().get(0).getWeeklyStats().getPercentileRank());
assertEquals(expectedPercentile, usage.getUsage().get(0).getMonthlyStats().getPercentileRank());
@ -195,38 +195,38 @@ public class UsageResourceTest extends CatalogApplicationTest {
String date = getDateStringByOffset(RestUtil.DATE_FORMAT, today, DAYS_OF_USAGE - 1);
// Number of days defaults to 1 when unspecified
UUID tableId = TABLES.get(0).getId();
getAndCheckUsage(TABLE, tableId, date, null /*, days unspecified */, 1, adminAuthHeaders());
getAndCheckUsage(TABLE, tableId, date, null /*, days unspecified */, 1, ADMIN_AUTH_HEADERS);
// Usage for specified number of days is returned
getAndCheckUsage(TABLE, tableId, date, 1, 1, adminAuthHeaders());
getAndCheckUsage(TABLE, tableId, date, 5, 5, adminAuthHeaders());
getAndCheckUsage(TABLE, tableId, date, 30, 30, adminAuthHeaders());
getAndCheckUsage(TABLE, tableId, date, 1, 1, ADMIN_AUTH_HEADERS);
getAndCheckUsage(TABLE, tableId, date, 5, 5, ADMIN_AUTH_HEADERS);
getAndCheckUsage(TABLE, tableId, date, 30, 30, ADMIN_AUTH_HEADERS);
// Usage for days out of range returned default number of days
// 0 days is defaulted to 1
getAndCheckUsage(TABLE, tableId, date, 0, 1, adminAuthHeaders());
getAndCheckUsage(TABLE, tableId, date, 0, 1, ADMIN_AUTH_HEADERS);
// -1 days is defaulted to 1
getAndCheckUsage(TABLE, tableId, date, -1, 1, adminAuthHeaders());
getAndCheckUsage(TABLE, tableId, date, -1, 1, ADMIN_AUTH_HEADERS);
// More than 30 days is defaulted to 30
getAndCheckUsage(TABLE, tableId, date, 100, 30, adminAuthHeaders());
getAndCheckUsage(TABLE, tableId, date, 100, 30, ADMIN_AUTH_HEADERS);
// Nothing is returned when usage for a date is not available
// One day beyond the last day of usage published
date = getDateStringByOffset(RestUtil.DATE_FORMAT, today, DAYS_OF_USAGE);
// 0 days of usage resulted
getAndCheckUsage(TABLE, tableId, date, 1, 0, adminAuthHeaders());
getAndCheckUsage(TABLE, tableId, date, 1, 0, ADMIN_AUTH_HEADERS);
// Only 4 past usage records returned. For the given date there is no usage report.
getAndCheckUsage(TABLE, tableId, date, 5, 4, adminAuthHeaders());
getAndCheckUsage(TABLE, tableId, date, 5, 4, ADMIN_AUTH_HEADERS);
// Ensure GET .../tables/{id}?fields=usageSummary returns the latest usage
date = getDateStringByOffset(RestUtil.DATE_FORMAT, today, DAYS_OF_USAGE - 1); // Latest usage report date
EntityUsage usage = getUsage(TABLE, tableId, date, null /* days not specified */, adminAuthHeaders());
Table table = new TableResourceTest().getEntity(TABLES.get(0).getId(), "usageSummary", adminAuthHeaders());
EntityUsage usage = getUsage(TABLE, tableId, date, null /* days not specified */, ADMIN_AUTH_HEADERS);
Table table = new TableResourceTest().getEntity(TABLES.get(0).getId(), "usageSummary", ADMIN_AUTH_HEADERS);
Assertions.assertEquals(usage.getUsage().get(0), table.getUsageSummary());
// Ensure GET .../databases/{id}?fields=usageSummary returns the latest usage
usage = getUsage(Entity.DATABASE, databaseId, date, null /* days not specified */, adminAuthHeaders());
Database database = new DatabaseResourceTest().getEntity(databaseId, "usageSummary", adminAuthHeaders());
usage = getUsage(Entity.DATABASE, databaseId, date, null /* days not specified */, ADMIN_AUTH_HEADERS);
Database database = new DatabaseResourceTest().getEntity(databaseId, "usageSummary", ADMIN_AUTH_HEADERS);
Assertions.assertEquals(usage.getUsage().get(0), database.getUsageSummary());
}

View File

@ -18,6 +18,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.openmetadata.catalog.security.SecurityUtil.authHeaders;
import java.net.URI;
import java.net.URISyntaxException;
@ -52,20 +53,18 @@ import org.openmetadata.catalog.type.TagLabel;
@Slf4j
public final class TestUtils {
// Entity name length allowed is 64 characters. This is a 65 char length invalid entity name
// Entity name length allowed is 128 characters
public static final int ENTITY_NAME_MAX_LEN = 128;
public static final String LONG_ENTITY_NAME;
static {
// Create an entity name with length longer than the
LONG_ENTITY_NAME = "1".repeat(ENTITY_NAME_MAX_LEN + 1);
}
public static final String ADMIN_USER_NAME = "admin";
public static final String LONG_ENTITY_NAME = "1".repeat(ENTITY_NAME_MAX_LEN + 1);
public static final String ENTITY_NAME_LENGTH_ERROR =
String.format("[name size must be between 1 and %d]", ENTITY_NAME_MAX_LEN);
public static final String ADMIN_USER_NAME = "admin";
public static final Map<String, String> ADMIN_AUTH_HEADERS = authHeaders(ADMIN_USER_NAME + "@open-metadata.org");
public static final Map<String, String> TEST_AUTH_HEADERS = authHeaders("test@open-metadata.org");
public static final UUID NON_EXISTENT_ENTITY = UUID.randomUUID();
public static final DatabaseConnection DATABASE_CONNECTION;
public static URI DASHBOARD_URL;
public static URI PIPELINE_URL;
@ -252,10 +251,10 @@ public final class TestUtils {
// So add to the expectedList, the derived tags before validating the tags
List<TagLabel> updatedExpectedList = new ArrayList<>(expectedList);
for (TagLabel expected : expectedList) {
Tag tag = TagResourceTest.getTag(expected.getTagFQN(), adminAuthHeaders());
Tag tag = TagResourceTest.getTag(expected.getTagFQN(), ADMIN_AUTH_HEADERS);
List<TagLabel> derived = new ArrayList<>();
for (String fqn : Optional.ofNullable(tag.getAssociatedTags()).orElse(Collections.emptyList())) {
Tag associatedTag = TagResourceTest.getTag(fqn, adminAuthHeaders());
Tag associatedTag = TagResourceTest.getTag(fqn, ADMIN_AUTH_HEADERS);
derived.add(
new TagLabel()
.withTagFQN(fqn)
@ -271,12 +270,8 @@ public final class TestUtils {
assertEquals(updatedExpectedList, actualList);
}
public static Map<String, String> adminAuthHeaders() {
return SecurityUtil.authHeaders(ADMIN_USER_NAME + "@open-metadata.org");
}
public static Map<String, String> userAuthHeaders() {
return SecurityUtil.authHeaders("test@open-metadata.org");
return authHeaders("test@open-metadata.org");
}
public static void checkUserFollowing(