Skip to content

Commit

Permalink
1660 - Link Query Examples to Terms (#1666)
Browse files Browse the repository at this point in the history
  • Loading branch information
Vladysl authored Apr 25, 2024
1 parent ac62047 commit ab1bbb3
Show file tree
Hide file tree
Showing 35 changed files with 1,036 additions and 97 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@
import static org.opendatadiscovery.oddplatform.dto.policy.PolicyPermissionDto.QUERY_EXAMPLE_DATASET_CREATE;
import static org.opendatadiscovery.oddplatform.dto.policy.PolicyPermissionDto.QUERY_EXAMPLE_DATASET_DELETE;
import static org.opendatadiscovery.oddplatform.dto.policy.PolicyPermissionDto.QUERY_EXAMPLE_DELETE;
import static org.opendatadiscovery.oddplatform.dto.policy.PolicyPermissionDto.QUERY_EXAMPLE_TERM_CREATE;
import static org.opendatadiscovery.oddplatform.dto.policy.PolicyPermissionDto.QUERY_EXAMPLE_TERM_DELETE;
import static org.opendatadiscovery.oddplatform.dto.policy.PolicyPermissionDto.QUERY_EXAMPLE_UPDATE;
import static org.opendatadiscovery.oddplatform.dto.policy.PolicyPermissionDto.ROLE_CREATE;
import static org.opendatadiscovery.oddplatform.dto.policy.PolicyPermissionDto.ROLE_DELETE;
Expand Down Expand Up @@ -182,6 +184,13 @@ NO_CONTEXT, new PathPatternParserServerWebExchangeMatcher(
TERM_OWNERSHIP_DELETE),
new SecurityRule(TERM, new PathPatternParserServerWebExchangeMatcher("/api/terms/{term_id}/tags", PUT),
TERM_TAGS_UPDATE),
new SecurityRule(TERM,
new PathPatternParserServerWebExchangeMatcher("/api/terms/{term_id}/queryexample", POST),
QUERY_EXAMPLE_TERM_CREATE),
new SecurityRule(TERM,
new PathPatternParserServerWebExchangeMatcher("/api/terms/{term_id}/queryexample/{example_id}",
DELETE),
QUERY_EXAMPLE_TERM_DELETE),
new SecurityRule(
DATA_ENTITY,
new PathPatternParserServerWebExchangeMatcher("/api/dataentities/{data_entity_id}/description", PUT),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ public Mono<ResponseEntity<QueryExampleList>> getQueryExampleByDatasetId(final L
.map(ResponseEntity::ok);
}

@Override
public Mono<ResponseEntity<QueryExampleList>> getQueryExampleByTermId(final Long termId,
final ServerWebExchange exchange) {
return queryExampleService.getQueryExampleByTermId(termId)
.map(ResponseEntity::ok);
}

@Override
public Mono<ResponseEntity<QueryExampleDetails>> getQueryExampleDetails(final Long exampleId,
final ServerWebExchange exchange) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import org.opendatadiscovery.oddplatform.api.contract.model.Ownership;
import org.opendatadiscovery.oddplatform.api.contract.model.OwnershipFormData;
import org.opendatadiscovery.oddplatform.api.contract.model.OwnershipUpdateFormData;
import org.opendatadiscovery.oddplatform.api.contract.model.QueryExample;
import org.opendatadiscovery.oddplatform.api.contract.model.QueryExampleTermFormData;
import org.opendatadiscovery.oddplatform.api.contract.model.Tag;
import org.opendatadiscovery.oddplatform.api.contract.model.TagsFormData;
import org.opendatadiscovery.oddplatform.api.contract.model.TermDetails;
Expand All @@ -21,6 +23,7 @@
import org.opendatadiscovery.oddplatform.api.contract.model.TermSearchFormData;
import org.opendatadiscovery.oddplatform.service.DataEntityService;
import org.opendatadiscovery.oddplatform.service.DatasetFieldService;
import org.opendatadiscovery.oddplatform.service.QueryExampleService;
import org.opendatadiscovery.oddplatform.service.term.TermOwnershipService;
import org.opendatadiscovery.oddplatform.service.term.TermSearchService;
import org.opendatadiscovery.oddplatform.service.term.TermService;
Expand All @@ -39,6 +42,7 @@ public class TermController implements TermApi {
private final DatasetFieldService datasetFieldService;
private final TermSearchService termSearchService;
private final TermOwnershipService termOwnershipService;
private final QueryExampleService queryExampleService;

@Override
public Mono<ResponseEntity<TermRefList>> getTermsList(final Integer page, final Integer size,
Expand Down Expand Up @@ -195,4 +199,22 @@ public Mono<ResponseEntity<TermSearchFacetsData>> updateTermSearchFacets(
.flatMap(fd -> termSearchService.updateFacets(searchId, fd))
.map(ResponseEntity::ok);
}

@Override
public Mono<ResponseEntity<QueryExample>>
createQueryExampleToTermRelationship(final Long termId,
final Mono<QueryExampleTermFormData> queryExampleTermFormData,
final ServerWebExchange exchange) {
return queryExampleTermFormData
.flatMap(item -> queryExampleService.linkTermWithQueryExample(termId, item))
.map(ResponseEntity::ok);
}

@Override
public Mono<ResponseEntity<Void>> deleteQueryExampleToTermRelationship(final Long termId,
final Long exampleId,
final ServerWebExchange exchange) {
return queryExampleService.removeTermFromQueryExample(termId, exampleId)
.thenReturn(ResponseEntity.noContent().build());
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package org.opendatadiscovery.oddplatform.dto;

import java.util.List;
import org.opendatadiscovery.oddplatform.dto.term.LinkedTermDto;
import org.opendatadiscovery.oddplatform.model.tables.pojos.DataEntityPojo;
import org.opendatadiscovery.oddplatform.model.tables.pojos.QueryExamplePojo;

public record QueryExampleDto(QueryExamplePojo queryExamplePojo,
List<DataEntityPojo> linkedEntities) {
List<DataEntityPojo> linkedEntities,
List<LinkedTermDto> linkedTerms) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ public enum PolicyPermissionDto {
TERM_OWNERSHIP_UPDATE(TERM),
TERM_OWNERSHIP_DELETE(TERM),
TERM_TAGS_UPDATE(TERM),
QUERY_EXAMPLE_TERM_CREATE(TERM),
QUERY_EXAMPLE_TERM_DELETE(TERM),
DATA_SOURCE_CREATE(MANAGEMENT),
DATA_SOURCE_UPDATE(MANAGEMENT),
DATA_SOURCE_DELETE(MANAGEMENT),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ public class TermDetailsDto {

public TermDetailsDto(final TermRefDto termRefDto) {
this.tags = null;
this.termDto = new TermDto(termRefDto, null, null, null);
this.termDto = new TermDto(termRefDto, null, null, null, null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ public class TermDto {
private final TermRefDto termRefDto;
private final Integer entitiesUsingCount;
private final Integer columnsUsingCount;
private final Integer queryExampleUsingCount;
private final Set<TermOwnershipDto> ownerships;
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.opendatadiscovery.oddplatform.api.contract.model.QueryExampleRefList;
import org.opendatadiscovery.oddplatform.dto.DataEntityDimensionsDto;
import org.opendatadiscovery.oddplatform.dto.QueryExampleDto;
import org.opendatadiscovery.oddplatform.dto.term.LinkedTermDto;
import org.opendatadiscovery.oddplatform.model.tables.pojos.DataEntityPojo;
import org.opendatadiscovery.oddplatform.model.tables.pojos.QueryExamplePojo;
import org.opendatadiscovery.oddplatform.utils.Page;
Expand All @@ -27,6 +28,7 @@
public abstract class QueryExampleMapper {
protected DataEntityMapper dataEntityMapper;
protected DateTimeMapper dateTimeMapper;
protected TermMapper termMapper;

@Autowired
public void setDateTimeMapper(final DateTimeMapper dateTimeMapper) {
Expand All @@ -38,6 +40,11 @@ public void setDataEntityMapper(final DataEntityMapper dataEntityMapper) {
this.dataEntityMapper = dataEntityMapper;
}

@Autowired
public void setTermMapper(final TermMapper termMapper) {
this.termMapper = termMapper;
}

public abstract QueryExamplePojo mapToPojo(final QueryExampleFormData dto);

public abstract QueryExamplePojo applyToPojo(final QueryExampleFormData dto,
Expand Down Expand Up @@ -72,17 +79,18 @@ public List<QueryExample> mapToQueryExampleList(
return queryExampleDtos
.stream()
.map(item -> mapToQueryExample(item.queryExamplePojo(),
item.linkedEntities()))
item.linkedEntities(), item.linkedTerms()))
.collect(Collectors.toList());
}

public QueryExample mapToQueryExample(
final QueryExamplePojo pojo, final List<DataEntityPojo> dataEntities) {
final QueryExamplePojo pojo, final List<DataEntityPojo> dataEntities, final List<LinkedTermDto> linkedTerms) {
return new QueryExample()
.id(pojo.getId())
.definition(pojo.getDefinition())
.query(pojo.getQuery())
.linkedEntities(mapDataEntityRefList(dataEntities));
.linkedEntities(mapDataEntityRefList(dataEntities))
.linkedTerms(termMapper.mapToLinkedTermList(linkedTerms));
}

public List<DataEntityRef> mapDataEntityRefList(final List<DataEntityPojo> dataEntities) {
Expand All @@ -92,13 +100,15 @@ public List<DataEntityRef> mapDataEntityRefList(final List<DataEntityPojo> dataE
}

public QueryExampleDetails mapToQueryExampleDetails(
final QueryExamplePojo pojo, final List<DataEntityDimensionsDto> dataEntities) {
final QueryExamplePojo pojo, final List<DataEntityDimensionsDto> dataEntities,
final List<LinkedTermDto> terms) {
return new QueryExampleDetails()
.id(pojo.getId())
.definition(pojo.getDefinition())
.query(pojo.getQuery())
.createdAt(dateTimeMapper.mapUTCDateTime(pojo.getCreatedAt()))
.updatedAt(dateTimeMapper.mapUTCDateTime(pojo.getUpdatedAt()))
.linkedEntities(dataEntityMapper.mapPojos(dataEntities));
.linkedEntities(dataEntityMapper.mapPojos(dataEntities))
.linkedTerms(termMapper.mapToLinkedTermList(terms));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
import org.opendatadiscovery.oddplatform.api.contract.model.LinkedTerm;
import org.opendatadiscovery.oddplatform.api.contract.model.LinkedTermList;
import org.opendatadiscovery.oddplatform.api.contract.model.PageInfo;
import org.opendatadiscovery.oddplatform.api.contract.model.Term;
import org.opendatadiscovery.oddplatform.api.contract.model.TermDetails;
Expand Down Expand Up @@ -55,6 +56,12 @@ default TermRefList mapToRefPage(final Page<TermRefDto> page) {

List<Term> mapToList(final List<TermDto> dtos);

List<LinkedTerm> mapListToLinkedTermList(final List<LinkedTermDto> dtos);

default LinkedTermList mapToLinkedTermList(final List<LinkedTermDto> dtos) {
return new LinkedTermList().items(mapListToLinkedTermList(dtos));
}

default TermList mapToPage(final Page<TermDto> page) {
return new TermList()
.items(mapToList(page.getData()))
Expand All @@ -68,6 +75,7 @@ default TermList mapToPage(final Page<TermDto> page) {
@Mapping(source = "dto.termDto.ownerships", target = "ownership")
@Mapping(source = "dto.termDto.entitiesUsingCount", target = "entitiesUsingCount")
@Mapping(source = "dto.termDto.columnsUsingCount", target = "columnsUsingCount")
@Mapping(source = "dto.termDto.queryExampleUsingCount", target = "queryExampleUsingCount")
TermDetails mapToDetails(final TermDetailsDto dto);

@Mapping(source = "dto.termRefDto.term", target = ".")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,24 @@

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.jooq.Record;
import org.jooq.Record1;
import org.jooq.SelectConditionStep;
import org.jooq.SelectHavingStep;
import org.jooq.Table;
import org.jooq.impl.DSL;
import org.opendatadiscovery.oddplatform.dto.QueryExampleDto;
import org.opendatadiscovery.oddplatform.dto.term.LinkedTermDto;
import org.opendatadiscovery.oddplatform.dto.term.TermRefDto;
import org.opendatadiscovery.oddplatform.model.tables.pojos.DataEntityPojo;
import org.opendatadiscovery.oddplatform.model.tables.pojos.DataEntityToQueryExamplePojo;
import org.opendatadiscovery.oddplatform.model.tables.pojos.NamespacePojo;
import org.opendatadiscovery.oddplatform.model.tables.pojos.QueryExamplePojo;
import org.opendatadiscovery.oddplatform.model.tables.pojos.QueryExampleToTermPojo;
import org.opendatadiscovery.oddplatform.model.tables.pojos.TermPojo;
import org.opendatadiscovery.oddplatform.model.tables.records.DataEntityToQueryExampleRecord;
import org.opendatadiscovery.oddplatform.repository.util.JooqQueryHelper;
import org.opendatadiscovery.oddplatform.repository.util.JooqReactiveOperations;
Expand All @@ -20,18 +28,25 @@
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import static java.util.function.Function.identity;
import static org.jooq.impl.DSL.field;
import static org.jooq.impl.DSL.jsonArrayAgg;
import static org.opendatadiscovery.oddplatform.model.Tables.DATA_ENTITY;
import static org.opendatadiscovery.oddplatform.model.Tables.DATA_ENTITY_TO_QUERY_EXAMPLE;
import static org.opendatadiscovery.oddplatform.model.Tables.NAMESPACE;
import static org.opendatadiscovery.oddplatform.model.Tables.QUERY_EXAMPLE;
import static org.opendatadiscovery.oddplatform.model.Tables.QUERY_EXAMPLE_TO_TERM;
import static org.opendatadiscovery.oddplatform.model.Tables.TERM;

@Repository
public class ReactiveDataEntityQueryExampleRelationRepositoryImpl
extends ReactiveAbstractSoftDeleteCRUDRepository<DataEntityToQueryExampleRecord, DataEntityToQueryExamplePojo>
implements ReactiveDataEntityQueryExampleRelationRepository {
private static final String AGG_DATA_ENTITIES_FIELD = "dataEntities";
private static final String QUERY_EXAMPLES_CTE = "query_examples_cte";
public static final String TERMS = "terms";
public static final String TERM_NAMESPACES = "term_namespaces";
public static final String TERM_RELATIONS = "term_relations";

private final JooqRecordHelper jooqRecordHelper;

Expand Down Expand Up @@ -60,17 +75,26 @@ public Mono<DataEntityToQueryExamplePojo> createRelationWithDataEntity(final lon
public Mono<QueryExampleDto> getQueryExampleDatasetRelations(final long queryExample) {
final SelectHavingStep<Record> query = DSL.select(QUERY_EXAMPLE.asterisk())
.select(jsonArrayAgg(field(DATA_ENTITY.asterisk().toString())).as(AGG_DATA_ENTITIES_FIELD))
.select(jsonArrayAgg(field(TERM.asterisk().toString())).as(TERMS))
.select(jsonArrayAgg(field(NAMESPACE.asterisk().toString())).as(TERM_NAMESPACES))
.select(jsonArrayAgg(field(QUERY_EXAMPLE_TO_TERM.asterisk().toString())).as(TERM_RELATIONS))
.from(QUERY_EXAMPLE)
.leftJoin(DATA_ENTITY_TO_QUERY_EXAMPLE)
.on(DATA_ENTITY_TO_QUERY_EXAMPLE.QUERY_EXAMPLE_ID.eq(QUERY_EXAMPLE.ID))
.leftJoin(DATA_ENTITY)
.on(DATA_ENTITY.ID.eq(DATA_ENTITY_TO_QUERY_EXAMPLE.DATA_ENTITY_ID))
.leftJoin(QUERY_EXAMPLE_TO_TERM)
.on(QUERY_EXAMPLE.ID.eq(QUERY_EXAMPLE_TO_TERM.QUERY_EXAMPLE_ID))
.leftJoin(TERM)
.on(QUERY_EXAMPLE_TO_TERM.TERM_ID.eq(TERM.ID)).and(TERM.DELETED_AT.isNull())
.leftJoin(NAMESPACE).on(TERM.NAMESPACE_ID.eq(NAMESPACE.ID))
.where(QUERY_EXAMPLE.ID.eq(queryExample))
.groupBy(QUERY_EXAMPLE.ID);

return jooqReactiveOperations.mono(query)
.map(r -> new QueryExampleDto(r.into(QUERY_EXAMPLE).into(QueryExamplePojo.class),
extractDataEntityPojos(r)));
extractDataEntityPojos(r),
extractTerms(r)));
}

@Override
Expand Down Expand Up @@ -107,22 +131,59 @@ public Flux<QueryExampleDto> getQueryExampleDatasetRelationsByDataEntity(final L
.as(queryExampleSelect)
.select(QUERY_EXAMPLE.asterisk())
.select(jsonArrayAgg(field(DATA_ENTITY.asterisk().toString())).as(AGG_DATA_ENTITIES_FIELD))
.select(jsonArrayAgg(field(TERM.asterisk().toString())).as(TERMS))
.select(jsonArrayAgg(field(NAMESPACE.asterisk().toString())).as(TERM_NAMESPACES))
.select(jsonArrayAgg(field(QUERY_EXAMPLE_TO_TERM.asterisk().toString())).as(TERM_RELATIONS))
.from(exampleCTE.getName())
.join(QUERY_EXAMPLE)
.on(QUERY_EXAMPLE.ID.eq(exampleCTE.field(DATA_ENTITY_TO_QUERY_EXAMPLE.QUERY_EXAMPLE_ID)))
.leftJoin(DATA_ENTITY_TO_QUERY_EXAMPLE)
.on(DATA_ENTITY_TO_QUERY_EXAMPLE.QUERY_EXAMPLE_ID.eq(QUERY_EXAMPLE.ID))
.leftJoin(DATA_ENTITY)
.on(DATA_ENTITY.ID.eq(DATA_ENTITY_TO_QUERY_EXAMPLE.DATA_ENTITY_ID))
.leftJoin(QUERY_EXAMPLE_TO_TERM)
.on(QUERY_EXAMPLE.ID.eq(QUERY_EXAMPLE_TO_TERM.QUERY_EXAMPLE_ID))
.leftJoin(TERM)
.on(QUERY_EXAMPLE_TO_TERM.TERM_ID.eq(TERM.ID)).and(TERM.DELETED_AT.isNull())
.leftJoin(NAMESPACE).on(TERM.NAMESPACE_ID.eq(NAMESPACE.ID))
.groupBy(QUERY_EXAMPLE.ID);

return jooqReactiveOperations.flux(query)
.map(r -> new QueryExampleDto(r.into(QUERY_EXAMPLE).into(QueryExamplePojo.class),
extractDataEntityPojos(r)));
extractDataEntityPojos(r),
extractTerms(r)
));
}

private List<DataEntityPojo> extractDataEntityPojos(final Record r) {
return new ArrayList<>(jooqRecordHelper.extractAggRelation(r, AGG_DATA_ENTITIES_FIELD,
DataEntityPojo.class));
}

private List<LinkedTermDto> extractTerms(final Record record) {
final Set<TermPojo> terms = jooqRecordHelper.extractAggRelation(record, TERMS, TermPojo.class);

final Map<Long, NamespacePojo> namespaces = jooqRecordHelper
.extractAggRelation(record, TERM_NAMESPACES, NamespacePojo.class)
.stream()
.collect(Collectors.toMap(NamespacePojo::getId, identity()));

final Map<Long, List<QueryExampleToTermPojo>> relations = jooqRecordHelper
.extractAggRelation(record, TERM_RELATIONS, QueryExampleToTermPojo.class)
.stream()
.collect(Collectors.groupingBy(QueryExampleToTermPojo::getTermId));

return terms.stream()
.map(pojo -> {
final TermRefDto termRefDto = TermRefDto.builder()
.term(pojo)
.namespace(namespaces.get(pojo.getNamespaceId()))
.build();
final boolean isDescriptionLink = relations.getOrDefault(pojo.getId(), List.of()).stream()
.anyMatch(r -> Boolean.TRUE.equals(r.getIsDescriptionLink()));

return new LinkedTermDto(termRefDto, isDescriptionLink);
})
.toList();
}
}
Loading

0 comments on commit ab1bbb3

Please sign in to comment.