-
Notifications
You must be signed in to change notification settings - Fork 3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(Tests): Metadata Tests Models + APIs + UI (Part 1) (#4989)
- Loading branch information
1 parent
8ac2bd6
commit 944be9a
Showing
44 changed files
with
2,247 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
81 changes: 81 additions & 0 deletions
81
...ql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/test/CreateTestResolver.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
package com.linkedin.datahub.graphql.resolvers.test; | ||
|
||
import com.linkedin.data.template.SetMode; | ||
import com.linkedin.datahub.graphql.QueryContext; | ||
import com.linkedin.datahub.graphql.exception.AuthorizationException; | ||
import com.linkedin.datahub.graphql.generated.CreateTestInput; | ||
import com.linkedin.entity.client.EntityClient; | ||
import com.linkedin.events.metadata.ChangeType; | ||
import com.linkedin.metadata.Constants; | ||
import com.linkedin.metadata.key.TestKey; | ||
import com.linkedin.metadata.utils.GenericRecordUtils; | ||
import com.linkedin.mxe.MetadataChangeProposal; | ||
import com.linkedin.test.TestInfo; | ||
import graphql.schema.DataFetcher; | ||
import graphql.schema.DataFetchingEnvironment; | ||
import java.util.UUID; | ||
import java.util.concurrent.CompletableFuture; | ||
|
||
import static com.linkedin.datahub.graphql.resolvers.ResolverUtils.*; | ||
import static com.linkedin.datahub.graphql.resolvers.test.TestUtils.*; | ||
|
||
|
||
/** | ||
* Creates or updates a Test. Requires the MANAGE_TESTS privilege. | ||
*/ | ||
public class CreateTestResolver implements DataFetcher<CompletableFuture<String>> { | ||
|
||
private final EntityClient _entityClient; | ||
|
||
public CreateTestResolver(final EntityClient entityClient) { | ||
_entityClient = entityClient; | ||
} | ||
|
||
@Override | ||
public CompletableFuture<String> get(final DataFetchingEnvironment environment) throws Exception { | ||
final QueryContext context = environment.getContext(); | ||
|
||
return CompletableFuture.supplyAsync(() -> { | ||
|
||
if (canManageTests(context)) { | ||
|
||
final CreateTestInput input = bindArgument(environment.getArgument("input"), CreateTestInput.class); | ||
final MetadataChangeProposal proposal = new MetadataChangeProposal(); | ||
|
||
// Create new test | ||
// Since we are creating a new Test, we need to generate a unique UUID. | ||
final UUID uuid = UUID.randomUUID(); | ||
final String uuidStr = input.getId() == null ? uuid.toString() : input.getId(); | ||
|
||
// Create the Ingestion source key | ||
final TestKey key = new TestKey(); | ||
key.setId(uuidStr); | ||
proposal.setEntityKeyAspect(GenericRecordUtils.serializeAspect(key)); | ||
|
||
// Create the Test info. | ||
final TestInfo info = mapCreateTestInput(input); | ||
proposal.setEntityType(Constants.TEST_ENTITY_NAME); | ||
proposal.setAspectName(Constants.TEST_INFO_ASPECT_NAME); | ||
proposal.setAspect(GenericRecordUtils.serializeAspect(info)); | ||
proposal.setChangeType(ChangeType.UPSERT); | ||
|
||
try { | ||
return _entityClient.ingestProposal(proposal, context.getAuthentication()); | ||
} catch (Exception e) { | ||
throw new RuntimeException(String.format("Failed to perform update against Test with urn %s", input.toString()), e); | ||
} | ||
} | ||
throw new AuthorizationException("Unauthorized to perform this action. Please contact your DataHub administrator."); | ||
}); | ||
} | ||
|
||
private static TestInfo mapCreateTestInput(final CreateTestInput input) { | ||
final TestInfo result = new TestInfo(); | ||
result.setName(input.getName()); | ||
result.setCategory(input.getCategory()); | ||
result.setDescription(input.getDescription(), SetMode.IGNORE_NULL); | ||
result.setDefinition(mapDefinition(input.getDefinition())); | ||
return result; | ||
} | ||
|
||
} |
42 changes: 42 additions & 0 deletions
42
...ql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/test/DeleteTestResolver.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package com.linkedin.datahub.graphql.resolvers.test; | ||
|
||
import com.linkedin.common.urn.Urn; | ||
import com.linkedin.datahub.graphql.QueryContext; | ||
import com.linkedin.datahub.graphql.exception.AuthorizationException; | ||
import com.linkedin.entity.client.EntityClient; | ||
import graphql.schema.DataFetcher; | ||
import graphql.schema.DataFetchingEnvironment; | ||
import java.util.concurrent.CompletableFuture; | ||
import static com.linkedin.datahub.graphql.resolvers.test.TestUtils.*; | ||
|
||
|
||
/** | ||
* Resolver responsible for hard deleting a particular DataHub Test. Requires MANAGE_TESTS | ||
* privilege. | ||
*/ | ||
public class DeleteTestResolver implements DataFetcher<CompletableFuture<Boolean>> { | ||
|
||
private final EntityClient _entityClient; | ||
|
||
public DeleteTestResolver(final EntityClient entityClient) { | ||
_entityClient = entityClient; | ||
} | ||
|
||
@Override | ||
public CompletableFuture<Boolean> get(final DataFetchingEnvironment environment) throws Exception { | ||
final QueryContext context = environment.getContext(); | ||
final String testUrn = environment.getArgument("urn"); | ||
final Urn urn = Urn.createFromString(testUrn); | ||
return CompletableFuture.supplyAsync(() -> { | ||
if (canManageTests(context)) { | ||
try { | ||
_entityClient.deleteEntity(urn, context.getAuthentication()); | ||
return true; | ||
} catch (Exception e) { | ||
throw new RuntimeException(String.format("Failed to perform delete against Test with urn %s", testUrn), e); | ||
} | ||
} | ||
throw new AuthorizationException("Unauthorized to perform this action. Please contact your DataHub administrator."); | ||
}); | ||
} | ||
} |
90 changes: 90 additions & 0 deletions
90
...hql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/test/ListTestsResolver.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
package com.linkedin.datahub.graphql.resolvers.test; | ||
|
||
import com.linkedin.common.urn.Urn; | ||
import com.linkedin.datahub.graphql.QueryContext; | ||
import com.linkedin.datahub.graphql.exception.AuthorizationException; | ||
import com.linkedin.datahub.graphql.generated.Test; | ||
import com.linkedin.datahub.graphql.generated.EntityType; | ||
import com.linkedin.datahub.graphql.generated.ListTestsInput; | ||
import com.linkedin.datahub.graphql.generated.ListTestsResult; | ||
import com.linkedin.entity.client.EntityClient; | ||
import com.linkedin.metadata.Constants; | ||
import com.linkedin.metadata.search.SearchEntity; | ||
import com.linkedin.metadata.search.SearchEntityArray; | ||
import com.linkedin.metadata.search.SearchResult; | ||
import graphql.schema.DataFetcher; | ||
import graphql.schema.DataFetchingEnvironment; | ||
import java.util.ArrayList; | ||
import java.util.Collections; | ||
import java.util.List; | ||
import java.util.concurrent.CompletableFuture; | ||
|
||
import static com.linkedin.datahub.graphql.resolvers.ResolverUtils.*; | ||
import static com.linkedin.datahub.graphql.resolvers.test.TestUtils.*; | ||
|
||
|
||
/** | ||
* Resolver used for listing all Tests defined within DataHub. Requires the MANAGE_DOMAINS platform privilege. | ||
*/ | ||
public class ListTestsResolver implements DataFetcher<CompletableFuture<ListTestsResult>> { | ||
|
||
private static final Integer DEFAULT_START = 0; | ||
private static final Integer DEFAULT_COUNT = 20; | ||
|
||
private final EntityClient _entityClient; | ||
|
||
public ListTestsResolver(final EntityClient entityClient) { | ||
_entityClient = entityClient; | ||
} | ||
|
||
@Override | ||
public CompletableFuture<ListTestsResult> get(final DataFetchingEnvironment environment) throws Exception { | ||
|
||
final QueryContext context = environment.getContext(); | ||
|
||
return CompletableFuture.supplyAsync(() -> { | ||
|
||
if (canManageTests(context)) { | ||
final ListTestsInput input = bindArgument(environment.getArgument("input"), ListTestsInput.class); | ||
final Integer start = input.getStart() == null ? DEFAULT_START : input.getStart(); | ||
final Integer count = input.getCount() == null ? DEFAULT_COUNT : input.getCount(); | ||
final String query = input.getQuery() == null ? "" : input.getQuery(); | ||
|
||
try { | ||
// First, get all group Urns. | ||
final SearchResult gmsResult = _entityClient.search( | ||
Constants.TEST_ENTITY_NAME, | ||
query, | ||
Collections.emptyMap(), | ||
start, | ||
count, | ||
context.getAuthentication()); | ||
|
||
// Now that we have entities we can bind this to a result. | ||
final ListTestsResult result = new ListTestsResult(); | ||
result.setStart(gmsResult.getFrom()); | ||
result.setCount(gmsResult.getPageSize()); | ||
result.setTotal(gmsResult.getNumEntities()); | ||
result.setTests(mapUnresolvedTests(gmsResult.getEntities())); | ||
return result; | ||
} catch (Exception e) { | ||
throw new RuntimeException("Failed to list tests", e); | ||
} | ||
} | ||
throw new AuthorizationException("Unauthorized to perform this action. Please contact your DataHub administrator."); | ||
}); | ||
} | ||
|
||
// This method maps urns returned from the list endpoint into Partial Test objects which will be resolved be a separate Batch resolver. | ||
private List<Test> mapUnresolvedTests(final SearchEntityArray entityArray) { | ||
final List<Test> results = new ArrayList<>(); | ||
for (final SearchEntity entity : entityArray) { | ||
final Urn urn = entity.getEntity(); | ||
final Test unresolvedTest = new Test(); | ||
unresolvedTest.setUrn(urn.toString()); | ||
unresolvedTest.setType(EntityType.TEST); | ||
results.add(unresolvedTest); | ||
} | ||
return results; | ||
} | ||
} |
Oops, something went wrong.