Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(versionedDataset): adds a versionStamp to timeline response & adds versionStamp param to dataset graphql #4727

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
1af4136
feat(versionedDataset): initial commit
RyanHolstien Apr 21, 2022
3110642
feat(versionedDataset): cover null versionStamp
RyanHolstien Apr 21, 2022
c5cd6c6
feat(versionedDataset): support returning versionStamp from the backend
RyanHolstien Apr 22, 2022
80318e1
feat(versionedDataset): fix graphql and timeline cli
RyanHolstien Apr 22, 2022
8148210
feat(versionedDataset): remove unused import
RyanHolstien Apr 22, 2022
3415866
feat(graphql): versioned dataset query - undeprecate schema for non-v…
RyanHolstien Apr 22, 2022
cacce49
feat(graphql): versioned dataset query - fix versionstamp creation bug
RyanHolstien Apr 23, 2022
d1b186b
Merge branch 'master' into feature/versionStamp
RyanHolstien Apr 25, 2022
29eefaf
feat(graphql): versioned dataset query - revert timeline cli change
RyanHolstien Apr 25, 2022
563e4f9
feat(graphql): versioned dataset query - handle partial versionStamps…
RyanHolstien Apr 27, 2022
c79f862
Merge branch 'master' into feature/versionStamp
RyanHolstien Apr 27, 2022
9c91147
feat(graphql): versioned dataset query - fix import
RyanHolstien Apr 27, 2022
23cb905
feat(graphql): versioned dataset query - update cassandra service to …
RyanHolstien Apr 27, 2022
2403710
feat(graphql): versioned dataset query - review comments
RyanHolstien Apr 28, 2022
edc2487
feat(graphql): dataset versioned query - add test
RyanHolstien Apr 28, 2022
36b08db
checkstyle
RyanHolstien Apr 28, 2022
4f923ba
checkstyle
RyanHolstien Apr 28, 2022
a7f29f1
change comment, force rebuild
RyanHolstien Apr 28, 2022
ddda27a
checkstyle
RyanHolstien Apr 28, 2022
8427360
feat(graphql): versioned dataset query - review comments: change from…
RyanHolstien Apr 28, 2022
7f16a76
checkstyle
RyanHolstien Apr 28, 2022
03ad8c2
feat(graphql): versioned dataset query - review comments: separate query
RyanHolstien Apr 28, 2022
988ddc8
feat(graphql): versioned dataset query - add relationship no-op
RyanHolstien Apr 29, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ public class Constants {
public static final String RECOMMENDATIONS_SCHEMA_FILE = "recommendation.graphql";
public static final String INGESTION_SCHEMA_FILE = "ingestion.graphql";
public static final String BROWSE_PATH_DELIMITER = "/";
public static final String VERSION_STAMP_FIELD_NAME = "versionStamp";
}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
/**
* Checks whether the user is currently authenticated & if so delegates execution to a child resolver.
*/
@Deprecated
public final class AuthenticatedResolver<T> implements DataFetcher<T> {

private final DataFetcher<T> _resolver;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ public class BrowsePathsResolver implements DataFetcher<CompletableFuture<List<B

private static final Logger _logger = LoggerFactory.getLogger(BrowsePathsResolver.class.getName());

private final Map<EntityType, BrowsableEntityType<?>> _typeToEntity;
private final Map<EntityType, BrowsableEntityType<?, ?>> _typeToEntity;

public BrowsePathsResolver(@Nonnull final List<BrowsableEntityType<?>> browsableEntities) {
public BrowsePathsResolver(@Nonnull final List<BrowsableEntityType<?, ?>> browsableEntities) {
_typeToEntity = browsableEntities.stream().collect(Collectors.toMap(
BrowsableEntityType::type,
entity -> entity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ public class BrowseResolver implements DataFetcher<CompletableFuture<BrowseResul

private static final Logger _logger = LoggerFactory.getLogger(BrowseResolver.class.getName());

private final Map<EntityType, BrowsableEntityType<?>> _typeToEntity;
private final Map<EntityType, BrowsableEntityType<?, ?>> _typeToEntity;

public BrowseResolver(@Nonnull final List<BrowsableEntityType<?>> browsableEntities) {
public BrowseResolver(@Nonnull final List<BrowsableEntityType<?, ?>> browsableEntities) {
_typeToEntity = browsableEntities.stream().collect(Collectors.toMap(
BrowsableEntityType::type,
entity -> entity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.linkedin.datahub.graphql.generated.Entity;
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;
Expand All @@ -22,30 +23,34 @@
*/
public class EntityTypeBatchResolver implements DataFetcher<CompletableFuture<List<Entity>>> {

private final List<com.linkedin.datahub.graphql.types.EntityType<?>> _entityTypes;
private final List<com.linkedin.datahub.graphql.types.EntityType<?, ?>> _entityTypes;
private final Function<DataFetchingEnvironment, List<Entity>> _entitiesProvider;

public EntityTypeBatchResolver(
final List<com.linkedin.datahub.graphql.types.EntityType<?>> entityTypes,
final List<com.linkedin.datahub.graphql.types.EntityType<?, ?>> entityTypes,
final Function<DataFetchingEnvironment, List<Entity>> entitiesProvider
) {
_entityTypes = entityTypes;
_entitiesProvider = entitiesProvider;
}

@Override
public CompletableFuture get(DataFetchingEnvironment environment) {
public CompletableFuture<List<Entity>> get(DataFetchingEnvironment environment) {
final List<Entity> entities = _entitiesProvider.apply(environment);
if (entities.isEmpty()) {
return CompletableFuture.completedFuture(Collections.emptyList());
}
// Assume all entities are of the same type
final com.linkedin.datahub.graphql.types.EntityType<?> filteredEntity =
final com.linkedin.datahub.graphql.types.EntityType filteredEntity =
Iterables.getOnlyElement(_entityTypes.stream()
.filter(entity -> entities.get(0).getClass().isAssignableFrom(entity.objectClass()))
.collect(Collectors.toList()));

final DataLoader<String, Entity> loader = environment.getDataLoaderRegistry().getDataLoader(filteredEntity.name());
return loader.loadMany(entities.stream().map(Entity::getUrn).collect(Collectors.toList()));
final DataLoader loader = environment.getDataLoaderRegistry().getDataLoader(filteredEntity.name());
List keyList = new ArrayList();
for (Entity entity : entities) {
keyList.add(filteredEntity.getKeyProvider().apply(entity));
}
return loader.loadMany(keyList);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@
public class EntityTypeResolver implements DataFetcher<CompletableFuture<Entity>> {

private static final List<String> IDENTITY_FIELDS = ImmutableList.of("__typename", "urn", "type");
private final List<com.linkedin.datahub.graphql.types.EntityType<?>> _entityTypes;
private final List<com.linkedin.datahub.graphql.types.EntityType<?, ?>> _entityTypes;
private final Function<DataFetchingEnvironment, Entity> _entityProvider;

public EntityTypeResolver(
final List<com.linkedin.datahub.graphql.types.EntityType<?>> entityTypes,
final List<com.linkedin.datahub.graphql.types.EntityType<?, ?>> entityTypes,
final Function<DataFetchingEnvironment, Entity> entity
) {
_entityTypes = entityTypes;
Expand All @@ -51,17 +51,18 @@ public CompletableFuture get(DataFetchingEnvironment environment) {
return CompletableFuture.completedFuture(null);
}

final String urn = resolvedEntity.getUrn();
final Object javaObject = _entityProvider.apply(environment);

if (isOnlySelectingIdentityFields(environment)) {
return CompletableFuture.completedFuture(javaObject);
}

final com.linkedin.datahub.graphql.types.EntityType<?> filteredEntity = Iterables.getOnlyElement(_entityTypes.stream()
final com.linkedin.datahub.graphql.types.EntityType filteredEntity = Iterables.getOnlyElement(_entityTypes.stream()
.filter(entity -> javaObject.getClass().isAssignableFrom(entity.objectClass()))
.collect(Collectors.toList()));
final DataLoader<String, Entity> loader = environment.getDataLoaderRegistry().getDataLoader(filteredEntity.name());
return loader.load(urn);
final DataLoader loader = environment.getDataLoaderRegistry().getDataLoader(filteredEntity.name());
final Object key = filteredEntity.getKeyProvider().apply(resolvedEntity);

return loader.load(key);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,25 @@
* for the provided {@link LoadableType} under the name provided by {@link LoadableType#name()}
*
* @param <T> the generated GraphQL POJO corresponding to the resolved type.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update with new generic

* @param <K> the key type for the DataLoader
*/
public class LoadableTypeBatchResolver<T> implements DataFetcher<CompletableFuture<List<T>>> {
public class LoadableTypeBatchResolver<T, K> implements DataFetcher<CompletableFuture<List<T>>> {

private final LoadableType<T> _loadableType;
private final Function<DataFetchingEnvironment, List<String>> _urnProvider;
private final LoadableType<T, K> _loadableType;
private final Function<DataFetchingEnvironment, List<K>> _keyProvider;

public LoadableTypeBatchResolver(final LoadableType<T> loadableType, final Function<DataFetchingEnvironment, List<String>> urnProvider) {
public LoadableTypeBatchResolver(final LoadableType<T, K> loadableType, final Function<DataFetchingEnvironment, List<K>> keyProvider) {
_loadableType = loadableType;
_urnProvider = urnProvider;
_keyProvider = keyProvider;
}

@Override
public CompletableFuture<List<T>> get(DataFetchingEnvironment environment) {
final List<String> urns = _urnProvider.apply(environment);
if (urns == null) {
final List<K> keys = _keyProvider.apply(environment);
if (keys == null) {
return null;
}
final DataLoader<String, T> loader = environment.getDataLoaderRegistry().getDataLoader(_loadableType.name());
return loader.loadMany(urns);
final DataLoader<K, T> loader = environment.getDataLoaderRegistry().getDataLoader(_loadableType.name());
return loader.loadMany(keys);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,25 @@
* for the provided {@link LoadableType} under the name provided by {@link LoadableType#name()}
*
* @param <T> the generated GraphQL POJO corresponding to the resolved type.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

* @param <K> the key type for the DataLoader
*/
public class LoadableTypeResolver<T> implements DataFetcher<CompletableFuture<T>> {
public class LoadableTypeResolver<T, K> implements DataFetcher<CompletableFuture<T>> {

private final LoadableType<T> _loadableType;
private final Function<DataFetchingEnvironment, String> _urnProvider;
private final LoadableType<T, K> _loadableType;
private final Function<DataFetchingEnvironment, K> _keyProvider;

public LoadableTypeResolver(final LoadableType<T> loadableType, final Function<DataFetchingEnvironment, String> urnProvider) {
public LoadableTypeResolver(final LoadableType<T, K> loadableType, final Function<DataFetchingEnvironment, K> keyProvider) {
_loadableType = loadableType;
_urnProvider = urnProvider;
_keyProvider = keyProvider;
}

@Override
public CompletableFuture<T> get(DataFetchingEnvironment environment) {
final String urn = _urnProvider.apply(environment);
if (urn == null) {
final K key = _keyProvider.apply(environment);
if (key == null) {
return null;
}
final DataLoader<String, T> loader = environment.getDataLoaderRegistry().getDataLoader(_loadableType.name());
return loader.load(urn);
final DataLoader<K, T> loader = environment.getDataLoaderRegistry().getDataLoader(_loadableType.name());
return loader.load(key);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,18 @@
*/
public class OwnerTypeResolver<T> implements DataFetcher<CompletableFuture<T>> {

private final List<LoadableType<?>> _loadableTypes;
private final List<LoadableType<?, ?>> _loadableTypes;
private final Function<DataFetchingEnvironment, OwnerType> _urnProvider;

public OwnerTypeResolver(final List<LoadableType<?>> loadableTypes, final Function<DataFetchingEnvironment, OwnerType> urnProvider) {
public OwnerTypeResolver(final List<LoadableType<?, ?>> loadableTypes, final Function<DataFetchingEnvironment, OwnerType> urnProvider) {
_loadableTypes = loadableTypes;
_urnProvider = urnProvider;
}

@Override
public CompletableFuture<T> get(DataFetchingEnvironment environment) {
final OwnerType ownerType = _urnProvider.apply(environment);
final LoadableType<?> filteredEntity = Iterables.getOnlyElement(_loadableTypes.stream()
final LoadableType<?, ?> filteredEntity = Iterables.getOnlyElement(_loadableTypes.stream()
.filter(entity -> ownerType.getClass().isAssignableFrom(entity.objectClass()))
.collect(Collectors.toList()));
final DataLoader<String, T> loader = environment.getDataLoaderRegistry().getDataLoader(filteredEntity.name());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ public class AutoCompleteForMultipleResolver implements DataFetcher<CompletableF

private static final Logger _logger = LoggerFactory.getLogger(AutoCompleteForMultipleResolver.class.getName());

private final Map<EntityType, SearchableEntityType<?>> _typeToEntity;
private final Map<EntityType, SearchableEntityType<?, ?>> _typeToEntity;

public AutoCompleteForMultipleResolver(@Nonnull final List<SearchableEntityType<?>> searchableEntities) {
public AutoCompleteForMultipleResolver(@Nonnull final List<SearchableEntityType<?, ?>> searchableEntities) {
_typeToEntity = searchableEntities.stream().collect(Collectors.toMap(
SearchableEntityType::type,
entity -> entity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ public class AutoCompleteResolver implements DataFetcher<CompletableFuture<AutoC

private static final Logger _logger = LoggerFactory.getLogger(AutoCompleteResolver.class.getName());

private final Map<EntityType, SearchableEntityType<?>> _typeToEntity;
private final Map<EntityType, SearchableEntityType<?, ?>> _typeToEntity;

public AutoCompleteResolver(@Nonnull final List<SearchableEntityType<?>> searchableEntities) {
public AutoCompleteResolver(@Nonnull final List<SearchableEntityType<?, ?>> searchableEntities) {
_typeToEntity = searchableEntities.stream().collect(Collectors.toMap(
SearchableEntityType::type,
entity -> entity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public class AutocompleteUtils {
private AutocompleteUtils() { }

public static CompletableFuture<AutoCompleteMultipleResults> batchGetAutocompleteResults(
List<SearchableEntityType<?>> entities,
List<SearchableEntityType<?, ?>> entities,
String sanitizedQuery,
AutoCompleteMultipleInput input,
DataFetchingEnvironment environment
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@
*/
public class EntityInterfaceTypeResolver implements TypeResolver {

private final List<EntityType<?>> _entities;
private final List<EntityType<?, ?>> _entities;

public EntityInterfaceTypeResolver(final List<EntityType<?>> entities) {
public EntityInterfaceTypeResolver(final List<EntityType<?, ?>> entities) {
_entities = entities;
}

@Override
public GraphQLObjectType getType(TypeResolutionEnvironment env) {
Object javaObject = env.getObject();
final LoadableType<?> filteredEntity = Iterables.getOnlyElement(_entities.stream()
final LoadableType<?, ?> filteredEntity = Iterables.getOnlyElement(_entities.stream()
.filter(entity -> javaObject.getClass().isAssignableFrom(entity.objectClass()))
.collect(Collectors.toList()));
return env.getSchema().getObjectType(filteredEntity.objectClass().getSimpleName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@
* Extension of {@link EntityType} containing methods required for 'browse' functionality.
*
* @param <T>: The GraphQL object type corresponding to the entity, must extend the `Entity` interface.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update

* @param <K> the key type for the DataLoader
*/
public interface BrowsableEntityType<T extends Entity> extends EntityType<T> {
public interface BrowsableEntityType<T extends Entity, K> extends EntityType<T, K> {

/**
* Retrieves {@link BrowseResults} corresponding to a given path, list of filters, start, & count.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
package com.linkedin.datahub.graphql.types;

import com.linkedin.datahub.graphql.generated.Entity;
import java.util.function.Function;


/**
* GQL graph type representing a top-level GMS entity (eg. Dataset, User, DataPlatform, Chart, etc.).
*
* @param <T>: The GraphQL object type corresponding to the entity, must be of type {@link Entity}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update

* @param <K> the key type for the DataLoader
*/
public interface EntityType<T extends Entity> extends LoadableType<T> {
public interface EntityType<T extends Entity, K> extends LoadableType<T, K> {

/**
* Retrieves the {@link com.linkedin.datahub.graphql.generated.EntityType} associated with the Graph type, eg. 'DATASET'
*/
com.linkedin.datahub.graphql.generated.EntityType type();

Function<Entity, K> getKeyProvider();

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@
* GQL graph type that can be loaded from a downstream service by primary key.
*
* @param <T>: The GraphQL object type corresponding to the type.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update

* @param <K> the key type for the DataLoader
*/
public interface LoadableType<T> {
public interface LoadableType<T, K> {

/**
* Returns generated GraphQL class associated with the type
Expand All @@ -29,20 +30,20 @@ default String name() {
/**
* Retrieves an entity by urn string. Null is provided in place of an entity object if an entity cannot be found.
*
* @param urn to retrieve
* @param key to retrieve
* @param context the {@link QueryContext} corresponding to the request.
*/
default DataFetcherResult<T> load(@Nonnull final String urn, @Nonnull final QueryContext context) throws Exception {
return batchLoad(ImmutableList.of(urn), context).get(0);
default DataFetcherResult<T> load(@Nonnull final K key, @Nonnull final QueryContext context) throws Exception {
return batchLoad(ImmutableList.of(key), context).get(0);
};

/**
* Retrieves an list of entities given a list of urn strings. The list returned is expected to
* be of same length of the list of urns, where nulls are provided in place of an entity object if an entity cannot be found.
*
* @param urns to retrieve
* @param keys to retrieve
* @param context the {@link QueryContext} corresponding to the request.
*/
List<DataFetcherResult<T>> batchLoad(@Nonnull final List<String> urns, @Nonnull final QueryContext context) throws Exception;
List<DataFetcherResult<T>> batchLoad(@Nonnull final List<K> keys, @Nonnull final QueryContext context) throws Exception;

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
* @param <T>: The GraphQL object type corresponding to the entity, must extend the `Entity` interface.
*/
@Deprecated
public interface SearchableEntityType<T extends Entity> extends EntityType<T> {
public interface SearchableEntityType<T extends Entity, K> extends EntityType<T, K> {

/**
* Deprecated - this is no longer used in favor of the search and searchAcrossEntities GraphQL resolver.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.linkedin.datahub.graphql.VersionedAspectKey;
import com.linkedin.datahub.graphql.QueryContext;
import com.linkedin.datahub.graphql.generated.Aspect;
import com.linkedin.datahub.graphql.types.LoadableType;
import com.linkedin.entity.EntityResponse;
import com.linkedin.entity.EnvelopedAspect;
import com.linkedin.entity.client.EntityClient;
Expand All @@ -15,14 +16,24 @@
import java.util.stream.Collectors;
import javax.annotation.Nonnull;


public class AspectType {
@Deprecated
public class AspectType implements LoadableType<Aspect, VersionedAspectKey> {
private final EntityClient _entityClient;

public AspectType(final EntityClient entityClient) {
_entityClient = entityClient;
}

@Override
public Class<Aspect> objectClass() {
return Aspect.class;
}

@Override
public String name() {
return AspectType.class.getSimpleName();
}

/**
* Retrieves an list of aspects given a list of {@link VersionedAspectKey} structs. The list returned is expected to
* be of same length of the list of keys, where nulls are provided in place of an aspect object if an entity cannot be found.
Expand Down
Loading