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(recommendations): Recommendations infra P1 #3455

Merged
merged 69 commits into from
Oct 27, 2021
Merged
Show file tree
Hide file tree
Changes from 57 commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
6d16e76
Add mock response
Oct 13, 2021
972789b
Revert entity resource
Oct 13, 2021
de7153d
Adding first round
jjoyce0510 Oct 15, 2021
e7cee72
Adding other scenarios to mocks
jjoyce0510 Oct 15, 2021
d621348
Merge branch 'master' into recommendations-base
jjoyce0510 Oct 15, 2021
43d6c85
Adding recs
jjoyce0510 Oct 15, 2021
21bc047
Adding new components
jjoyce0510 Oct 15, 2021
7498c41
Platform card
jjoyce0510 Oct 18, 2021
32b490c
Adjusting
jjoyce0510 Oct 18, 2021
22b6d20
Add base pdl
Oct 19, 2021
62ff634
Merge branch 'recommendations-base' of https://github.com/acryldata/d…
Oct 19, 2021
f173dd2
Add recommendations service
Oct 19, 2021
05fb34a
Half working
Oct 19, 2021
3a2c849
Finalizing EntityNameList renderer
jjoyce0510 Oct 19, 2021
6d0e6b7
Finalized adding the first wave of recommendations
jjoyce0510 Oct 19, 2021
f1912c4
Adding a bunch of components
jjoyce0510 Oct 19, 2021
8931539
Merge branch 'recommendations-base' of https://github.com/acryldata/d…
jjoyce0510 Oct 19, 2021
94c19c7
Finalizing first pass of recommendations UI
jjoyce0510 Oct 19, 2021
63d2dd0
Reverse order
Oct 19, 2021
c897c19
Merge branch 'recommendations-base' of https://github.com/acryldata/d…
Oct 20, 2021
eaadf32
DONEga -u
Oct 20, 2021
324826a
Adding tracking events
jjoyce0510 Oct 20, 2021
da8a136
Merge branch 'recommendations-base' of https://github.com/acryldata/d…
jjoyce0510 Oct 20, 2021
bfa154a
Add top tags
Oct 20, 2021
86c35d5
Merging gabes changes
jjoyce0510 Oct 21, 2021
c93894f
Addressing UI feedbacks:
jjoyce0510 Oct 21, 2021
a5cf291
Fixing UI
jjoyce0510 Oct 21, 2021
eeadfd1
Added more modules
Oct 21, 2021
4ed57cc
Merge branch 'recommendations-base' of https://github.com/acryldata/d…
Oct 21, 2021
e44a460
Fix
Oct 21, 2021
1fc2801
Fix yarn test
jjoyce0510 Oct 21, 2021
591f6fa
False
jjoyce0510 Oct 21, 2021
a159f9a
Merge branch 'recommendations-base' of https://github.com/acryldata/d…
Oct 21, 2021
eb09b66
In progress
Oct 22, 2021
0c42a1d
Add recommendations
jjoyce0510 Oct 22, 2021
1a48d8f
Merge branch 'recommendations-base' of https://github.com/acryldata/d…
Oct 22, 2021
b4f2e91
Adding smoke tests
jjoyce0510 Oct 22, 2021
bdb57ac
adding rec ui tests
jjoyce0510 Oct 22, 2021
3f35d75
Fix search scroll
jjoyce0510 Oct 22, 2021
5c34287
Fix
Oct 22, 2021
d44a9a9
Merge branch 'recommendations-base' of https://github.com/acryldata/d…
Oct 22, 2021
347963e
Fixing linting
jjoyce0510 Oct 22, 2021
8d6990a
Merge branch 'recommendations-base' of https://github.com/acryldata/d…
jjoyce0510 Oct 22, 2021
ddccf35
Fix flickering etc
jjoyce0510 Oct 22, 2021
505e622
Add unit tests
Oct 25, 2021
18e7820
Merge branch 'recommendations-base' of https://github.com/acryldata/d…
Oct 25, 2021
74e107d
Fixed tests
jjoyce0510 Oct 26, 2021
a55e557
Recommendations first pass
jjoyce0510 Oct 26, 2021
53ba301
Merge remote-tracking branch 'acryl/recommendations-base' into recomm…
jjoyce0510 Oct 26, 2021
844cf57
Add relationships check
jjoyce0510 Oct 26, 2021
b441125
Merge remote-tracking branch 'acryl/recommendations-base' into recomm…
jjoyce0510 Oct 26, 2021
fd2826c
Fixing graphclient creation
jjoyce0510 Oct 26, 2021
84101dc
Merge remote-tracking branch 'acryl/recommendations-base' into recomm…
jjoyce0510 Oct 26, 2021
bbaf983
remove unused resolver
jjoyce0510 Oct 26, 2021
68d8e49
Merge remote-tracking branch 'acryl/recommendations-base' into recomm…
jjoyce0510 Oct 26, 2021
f672e85
Minor naming changes
jjoyce0510 Oct 26, 2021
048dc1d
Merge remote-tracking branch 'acryl/recommendations-base' into recomm…
jjoyce0510 Oct 26, 2021
ab09dab
Return empty recs by default
jjoyce0510 Oct 26, 2021
d91aa5e
merging
jjoyce0510 Oct 27, 2021
c7c39fb
Refactoring
jjoyce0510 Oct 27, 2021
22f3ae6
Merge remote-tracking branch 'acryl/recommendations-base' into recomm…
jjoyce0510 Oct 27, 2021
0067257
fixing conflicts
jjoyce0510 Oct 27, 2021
95af910
Merge remote-tracking branch 'acryl/recommendations-base' into recomm…
jjoyce0510 Oct 27, 2021
365eb41
Removing console logs
jjoyce0510 Oct 27, 2021
e064e16
Merge remote-tracking branch 'acryl/recommendations-base' into recomm…
jjoyce0510 Oct 27, 2021
c92bde2
remove unnecessary code
jjoyce0510 Oct 27, 2021
fc4f686
Merge remote-tracking branch 'acryl/recommendations-base' into recomm…
jjoyce0510 Oct 27, 2021
93159ff
remove unnecessary import
jjoyce0510 Oct 27, 2021
ee2e0ab
Merge remote-tracking branch 'acryl/recommendations-base' into recomm…
jjoyce0510 Oct 27, 2021
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
1 change: 1 addition & 0 deletions datahub-graphql-core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ graphqlCodegen {
"$projectDir/src/main/resources/app.graphql".toString(),
"$projectDir/src/main/resources/search.graphql".toString(),
"$projectDir/src/main/resources/analytics.graphql".toString(),
"$projectDir/src/main/resources/recommendation.graphql".toString(),
]
outputDir = new File("$projectDir/src/mainGeneratedGraphQL/java")
packageName = "com.linkedin.datahub.graphql.generated"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ public class Constants {
public static final String SEARCH_SCHEMA_FILE = "search.graphql";
public static final String APP_SCHEMA_FILE = "app.graphql";
public static final String ANALYTICS_SCHEMA_FILE = "analytics.graphql";
public static final String RECOMMENDATIONS_SCHEMA_FILE = "recommendation.graphql";
public static final String BROWSE_PATH_DELIMITER = "/";
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.linkedin.datahub.graphql.generated.EntityRelationshipLegacy;
import com.linkedin.datahub.graphql.generated.ForeignKeyConstraint;
import com.linkedin.datahub.graphql.generated.MLModelProperties;
import com.linkedin.datahub.graphql.generated.RecommendationContent;
import com.linkedin.datahub.graphql.generated.SearchResult;
import com.linkedin.datahub.graphql.generated.InstitutionalMemoryMetadata;
import com.linkedin.datahub.graphql.generated.UsageQueryResult;
Expand Down Expand Up @@ -65,6 +66,7 @@
import com.linkedin.datahub.graphql.resolvers.policy.ListPoliciesResolver;
import com.linkedin.datahub.graphql.resolvers.config.AppConfigResolver;
import com.linkedin.datahub.graphql.resolvers.policy.UpsertPolicyResolver;
import com.linkedin.datahub.graphql.resolvers.recommendation.ListRecommendationsResolver;
import com.linkedin.datahub.graphql.resolvers.search.SearchAcrossEntitiesResolver;
import com.linkedin.datahub.graphql.resolvers.type.AspectInterfaceTypeResolver;
import com.linkedin.datahub.graphql.resolvers.type.HyperParameterValueTypeResolver;
Expand Down Expand Up @@ -108,6 +110,7 @@
import com.linkedin.datahub.graphql.types.usage.UsageType;
import com.linkedin.entity.client.EntityClient;
import com.linkedin.metadata.entity.EntityService;
import com.linkedin.metadata.recommendation.RecommendationsService;
import com.linkedin.metadata.graph.GraphClient;
import graphql.execution.DataFetcherResult;
import graphql.schema.idl.RuntimeWiring;
Expand Down Expand Up @@ -144,6 +147,7 @@ public class GmsGraphQLEngine {
private final AnalyticsService analyticsService;
private final EntityClient entityClient;
private final EntityService entityService;
private final RecommendationsService _recommendationsService;
private final GraphClient graphClient;

private final DatasetType datasetType;
Expand Down Expand Up @@ -196,19 +200,21 @@ public class GmsGraphQLEngine {
public final List<BrowsableEntityType<?>> browsableTypes;

public GmsGraphQLEngine() {
this(null, null, null, null);
this(null, null, null, null, null);
}

public GmsGraphQLEngine(
final AnalyticsService analyticsService,
final EntityService entityService,
final RecommendationsService recommendationsService,
final GraphClient graphClient,
final EntityClient entityClient
) {
this.analyticsService = analyticsService;
this.entityClient = entityClient;
this.entityService = entityService;
this._recommendationsService = recommendationsService;
this.graphClient = graphClient;
this.entityClient = entityClient;

this.datasetType = new DatasetType(entityClient);
this.corpUserType = new CorpUserType(entityClient);
Expand Down Expand Up @@ -299,6 +305,18 @@ public static String analyticsSchema() {
return analyticsSchemaString;
}

public static String recommendationsSchema() {
String recommendationsSchemaString;
try {
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(RECOMMENDATIONS_SCHEMA_FILE);
recommendationsSchemaString = IOUtils.toString(is, StandardCharsets.UTF_8);
is.close();
} catch (IOException e) {
throw new RuntimeException("Failed to find GraphQL Schema with name " + RECOMMENDATIONS_SCHEMA_FILE, e);
}
return recommendationsSchemaString;
}

/**
* Returns a {@link Supplier} responsible for creating a new {@link DataLoader} from
* a {@link LoadableType}.
Expand Down Expand Up @@ -337,6 +355,7 @@ public GraphQLEngine.Builder builder() {
.addSchema(searchSchema())
.addSchema(appSchema())
.addSchema(analyticsSchema())
.addSchema(recommendationsSchema())
.addDataLoaders(loaderSuppliers(loadableTypes))
.addDataLoader("Aspect", (context) -> createAspectLoader(context))
.addDataLoader("UsageQueryResult", (context) -> createUsageLoader(context))
Expand Down Expand Up @@ -420,6 +439,8 @@ private void configureQueryResolvers(final RuntimeWiring.Builder builder) {
new ListUsersResolver(GmsClientFactory.getEntitiesClient()))
.dataFetcher("listGroups",
new ListGroupsResolver(GmsClientFactory.getEntitiesClient()))
.dataFetcher("listRecommendations",
new ListRecommendationsResolver(_recommendationsService))
.dataFetcher("getEntityCounts",
new EntityCountsResolver(GmsClientFactory.getEntitiesClient()))
);
Expand Down Expand Up @@ -469,6 +490,11 @@ private void configureGenericEntityResolvers(final RuntimeWiring.Builder builder
entityTypes.stream().collect(Collectors.toList()),
(env) -> ((AggregationMetadata) env.getSource()).getEntity()))
)
.type("RecommendationContent", typeWiring -> typeWiring
.dataFetcher("entity", new EntityTypeResolver(
entityTypes.stream().collect(Collectors.toList()),
(env) -> ((RecommendationContent) env.getSource()).getEntity()))
)
.type("BrowseResults", typeWiring -> typeWiring
.dataFetcher("entities", new AuthenticatedResolver<>(
new EntityTypeBatchResolver(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,275 @@
package com.linkedin.datahub.graphql.resolvers.recommendation;

import com.google.common.collect.ImmutableList;
import com.linkedin.common.urn.Urn;
import com.linkedin.datahub.graphql.generated.ContentParams;
import com.linkedin.datahub.graphql.generated.EntityProfileParams;
import com.linkedin.datahub.graphql.generated.Filter;
import com.linkedin.datahub.graphql.generated.ListRecommendationsInput;
import com.linkedin.datahub.graphql.generated.ListRecommendationsResult;
import com.linkedin.datahub.graphql.generated.RecommendationContent;
import com.linkedin.datahub.graphql.generated.RecommendationModule;
import com.linkedin.datahub.graphql.generated.RecommendationParams;
import com.linkedin.datahub.graphql.generated.RecommendationRenderType;
import com.linkedin.datahub.graphql.generated.RecommendationRequestContext;
import com.linkedin.datahub.graphql.generated.SearchParams;
import com.linkedin.datahub.graphql.resolvers.EntityTypeMapper;
import com.linkedin.datahub.graphql.types.common.mappers.UrnToEntityMapper;
import com.linkedin.metadata.query.filter.Criterion;
import com.linkedin.metadata.query.filter.CriterionArray;
import com.linkedin.metadata.recommendation.EntityRequestContext;
import com.linkedin.metadata.recommendation.RecommendationsService;
import com.linkedin.metadata.recommendation.SearchRequestContext;
import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import static com.linkedin.datahub.graphql.resolvers.ResolverUtils.bindArgument;


@Slf4j
@RequiredArgsConstructor
public class ListRecommendationsResolver implements DataFetcher<CompletableFuture<ListRecommendationsResult>> {
private final RecommendationsService _recommendationsService;

@Override
public CompletableFuture<ListRecommendationsResult> get(DataFetchingEnvironment environment) {
final ListRecommendationsInput input =
bindArgument(environment.getArgument("input"), ListRecommendationsInput.class);

return CompletableFuture.supplyAsync(() -> {
try {
shirshanka marked this conversation as resolved.
Show resolved Hide resolved
log.debug("Listing recommendations for input {}", input);
List<com.linkedin.metadata.recommendation.RecommendationModule> modules =
_recommendationsService.listRecommendations(Urn.createFromString(input.getUserUrn()),
mapRequestContext(input.getRequestContext()), input.getLimit());
return ListRecommendationsResult.builder()
.setModules(modules.stream()
.map(this::mapRecommendationModule)
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList()))
.build();
} catch (Exception e) {
log.error("Failed to get recommendations for input {}", input);
throw new RuntimeException("Failed to get recommendations for input " + input, e);
}
});
}

private com.linkedin.metadata.recommendation.RecommendationRequestContext mapRequestContext(
RecommendationRequestContext requestContext) {
com.linkedin.metadata.recommendation.ScenarioType mappedScenarioType;
try {
mappedScenarioType =
com.linkedin.metadata.recommendation.ScenarioType.valueOf(requestContext.getScenario().toString());
} catch (IllegalArgumentException e) {
log.error("Failed to map scenario type: {}", requestContext.getScenario(), e);
throw e;
}
com.linkedin.metadata.recommendation.RecommendationRequestContext mappedRequestContext =
new com.linkedin.metadata.recommendation.RecommendationRequestContext().setScenario(mappedScenarioType);
if (requestContext.getSearchRequestContext() != null) {
SearchRequestContext searchRequestContext =
new SearchRequestContext().setQuery(requestContext.getSearchRequestContext().getQuery());
if (requestContext.getSearchRequestContext().getFilters() != null) {
searchRequestContext.setFilters(new CriterionArray(requestContext.getSearchRequestContext()
.getFilters()
.stream()
.map(facetField -> new Criterion().setField(facetField.getField()).setValue(facetField.getValue()))
.collect(Collectors.toList())));
}
mappedRequestContext.setSearchRequestContext(searchRequestContext);
}
if (requestContext.getEntityRequestContext() != null) {
Urn entityUrn;
try {
entityUrn = Urn.createFromString(requestContext.getEntityRequestContext().getUrn());
} catch (URISyntaxException e) {
log.error("Malformed URN while mapping recommendations request: {}",
requestContext.getEntityRequestContext().getUrn(), e);
throw new IllegalArgumentException(e);
}
EntityRequestContext entityRequestContext = new EntityRequestContext().setUrn(entityUrn)
.setType(EntityTypeMapper.getName(requestContext.getEntityRequestContext().getType()));
mappedRequestContext.setEntityRequestContext(entityRequestContext);
}
return mappedRequestContext;
}

private Optional<RecommendationModule> mapRecommendationModule(
com.linkedin.metadata.recommendation.RecommendationModule module) {
RecommendationModule mappedModule = new RecommendationModule();
mappedModule.setTitle(module.getTitle());
mappedModule.setModuleId(module.getModuleId());
try {
mappedModule.setRenderType(RecommendationRenderType.valueOf(module.getRenderType().toString()));
} catch (IllegalArgumentException e) {
log.error("Failed to map render type: {}", module.getRenderType(), e);
throw e;
}
mappedModule.setContent(
module.getContent().stream().map(this::mapRecommendationContent).collect(Collectors.toList()));
return Optional.of(mappedModule);
}

private RecommendationContent mapRecommendationContent(
com.linkedin.metadata.recommendation.RecommendationContent content) {
RecommendationContent mappedContent = new RecommendationContent();
mappedContent.setValue(content.getValue());
if (content.hasEntity()) {
mappedContent.setEntity(UrnToEntityMapper.map(content.getEntity()));
}
if (content.hasParams()) {
mappedContent.setParams(mapRecommendationParams(content.getParams()));
}
return mappedContent;
}

private RecommendationParams mapRecommendationParams(
com.linkedin.metadata.recommendation.RecommendationParams params) {
RecommendationParams mappedParams = new RecommendationParams();
if (params.hasSearchParams()) {
SearchParams searchParams = new SearchParams();
searchParams.setQuery(params.getSearchParams().getQuery());
if (!params.getSearchParams().getFilters().isEmpty()) {
searchParams.setFilters(params.getSearchParams()
.getFilters()
.stream()
.map(criterion -> Filter.builder().setField(criterion.getField()).setValue(criterion.getValue()).build())
.collect(Collectors.toList()));
}
mappedParams.setSearchParams(searchParams);
}

if (params.hasEntityProfileParams()) {
mappedParams.setEntityProfileParams(
EntityProfileParams.builder().setUrn(params.getEntityProfileParams().getUrn().toString()).build());
}

if (params.hasContentParams()) {
mappedParams.setContentParams(ContentParams.builder().setCount(params.getContentParams().getCount()).build());
}

return mappedParams;
}

private ListRecommendationsResult createMockSearchResults() {
// Popular Tags
List<String> popularTagList =
ImmutableList.of("urn:li:tag:Legacy", "urn:li:tag:Email", "urn:li:tag:PII", "urn:li:tag:Highly Confidential",
"urn:li:tag:Marketing", "urn:li:tag:SalesDev", "urn:li:tag:MemberRefreshQ3");
RecommendationModule popularTags = new RecommendationModule();
popularTags.setTitle("Popular Tags");
popularTags.setModuleId("PopularTags");
popularTags.setRenderType(RecommendationRenderType.TAG_SEARCH_LIST);
popularTags.setContent(popularTagList.stream().map(this::createTagSearchRec).collect(Collectors.toList()));

return ListRecommendationsResult.builder().setModules(ImmutableList.of(popularTags)).build();
}

private ListRecommendationsResult createMockEntityResults() {
// People also viewed
List<String> peopleAlsoViewed = ImmutableList.of("urn:li:dataset:(urn:li:dataPlatform:hive,SampleHiveDataset,PROD)",
"urn:li:dataset:(urn:li:dataPlatform:hdfs,SampleHdfsDataset,PROD)", "urn:li:dashboard:(looker,baz)",
"urn:li:glossaryTerm:AccountBalance");
RecommendationModule peopleAlsoViewedModule = new RecommendationModule();
peopleAlsoViewedModule.setTitle("People also viewed");
peopleAlsoViewedModule.setModuleId("PeopleAlsoViewed");
peopleAlsoViewedModule.setRenderType(RecommendationRenderType.ENTITY_NAME_LIST);
peopleAlsoViewedModule.setContent(
peopleAlsoViewed.stream().map(this::createEntityRec).collect(Collectors.toList()));

return ListRecommendationsResult.builder().setModules(ImmutableList.of(peopleAlsoViewedModule)).build();
}

private ListRecommendationsResult createMockHomeResults() {
// Top platforms
List<String> platforms =
ImmutableList.of("urn:li:dataPlatform:bigquery", "urn:li:dataPlatform:snowflake", "urn:li:dataPlatform:looker",
"urn:li:dataPlatform:airflow");
RecommendationModule topPlatformModule = new RecommendationModule();
topPlatformModule.setTitle("Top Platforms");
topPlatformModule.setModuleId("TopPlatforms");
topPlatformModule.setRenderType(RecommendationRenderType.PLATFORM_SEARCH_LIST);
topPlatformModule.setContent(platforms.stream().map(this::createPlatformRec).collect(Collectors.toList()));

// Recently Viewed
List<String> recentlyViewed = ImmutableList.of("urn:li:dataset:(urn:li:dataPlatform:hive,SampleHiveDataset,PROD)",
"urn:li:dataset:(urn:li:dataPlatform:hdfs,SampleHdfsDataset,PROD)", "urn:li:dashboard:(looker,baz)",
"urn:li:corpuser:datahub", "urn:li:corpGroup:bfoo");
RecommendationModule recentlyViewedModule = new RecommendationModule();
recentlyViewedModule.setTitle("Recently Viewed");
recentlyViewedModule.setModuleId("RecentlyViewed");
recentlyViewedModule.setRenderType(RecommendationRenderType.ENTITY_NAME_LIST);
recentlyViewedModule.setContent(recentlyViewed.stream().map(this::createEntityRec).collect(Collectors.toList()));

// Popular entities
List<String> popularEntities = ImmutableList.of("urn:li:dataset:(urn:li:dataPlatform:hive,fct_users_created,PROD)",
"urn:li:dataset:(urn:li:dataPlatform:hdfs,logging_events,PROD)", "urn:li:dataFlow:(airflow,dag_abc,PROD)",
"urn:li:mlFeatureTable:(urn:li:dataPlatform:feast,user_analytics)");
RecommendationModule popularEntitiesModule = new RecommendationModule();
popularEntitiesModule.setTitle("Most Popular");
popularEntitiesModule.setModuleId("PopularEntities");
popularEntitiesModule.setRenderType(RecommendationRenderType.ENTITY_NAME_LIST);
popularEntitiesModule.setContent(popularEntities.stream().map(this::createEntityRec).collect(Collectors.toList()));

return ListRecommendationsResult.builder()
.setModules(ImmutableList.of(topPlatformModule, recentlyViewedModule, popularEntitiesModule))
.build();
}

private RecommendationContent createPlatformRec(String platformUrn) {
RecommendationContent content = new RecommendationContent();
content.setValue(platformUrn);
try {
content.setEntity(UrnToEntityMapper.map(Urn.createFromString(platformUrn)));
} catch (URISyntaxException e) {
log.error("Invalid urn: {}", platformUrn);
}
content.setParams(RecommendationParams.builder()
.setSearchParams(SearchParams.builder()
.setQuery("")
.setFilters(ImmutableList.of(Filter.builder().setField("platform").setValue(platformUrn).build()))
.build())
.build());
return content;
}

private RecommendationContent createEntityRec(String entityUrn) {
RecommendationContent content = new RecommendationContent();
content.setValue(entityUrn);
try {
content.setEntity(UrnToEntityMapper.map(Urn.createFromString(entityUrn)));
} catch (URISyntaxException e) {
log.error("Invalid urn: {}", entityUrn);
}
content.setParams(RecommendationParams.builder()
.setEntityProfileParams(EntityProfileParams.builder().setUrn(entityUrn).build())
.build());
return content;
}

private RecommendationContent createTagSearchRec(String tagUrn) {
RecommendationContent content = new RecommendationContent();
content.setValue(tagUrn);
try {
content.setEntity(UrnToEntityMapper.map(Urn.createFromString(tagUrn)));
} catch (URISyntaxException e) {
log.error("Invalid urn: {}", tagUrn);
}
content.setParams(RecommendationParams.builder()
.setSearchParams(SearchParams.builder()
.setQuery("")
.setFilters(ImmutableList.of(Filter.builder().setField("tags").setValue(tagUrn).build()))
.build())
.build());
return content;
}
}
Loading