Search in sources :

Example 6 with Sorting

use of com.yahoo.elide.core.request.Sorting in project elide by yahoo.

the class DataStoreLoadTest method testPaginationPageTwo.

@Test
public void testPaginationPageTwo() throws Exception {
    DataStoreTransaction testTransaction = searchStore.beginReadTransaction();
    Map<String, Sorting.SortOrder> sortRules = new HashMap<>();
    sortRules.put("name", Sorting.SortOrder.desc);
    sortRules.put("modifiedDate", Sorting.SortOrder.asc);
    Sorting sorting = new SortingImpl(sortRules, Item.class, dictionary);
    PaginationImpl pagination = new PaginationImpl(Item.class, 1, 1, PaginationImpl.DEFAULT_PAGE_LIMIT, PaginationImpl.MAX_PAGE_LIMIT, true, false);
    FilterExpression filter = filterParser.parseFilterExpression("name==cymbal*", ClassType.of(Item.class), false);
    Iterable<Object> loaded = testTransaction.loadObjects(EntityProjection.builder().type(Item.class).filterExpression(filter).sorting(sorting).pagination(pagination).build(), mockScope);
    assertListMatches(loaded, Lists.newArrayList(5L));
    assertEquals(pagination.getPageTotals(), 3);
    verify(wrappedTransaction, never()).loadObjects(any(), any());
}
Also used : Item(com.yahoo.elide.datastores.search.models.Item) PaginationImpl(com.yahoo.elide.core.pagination.PaginationImpl) HashMap(java.util.HashMap) SortingImpl(com.yahoo.elide.core.sort.SortingImpl) DataStoreTransaction(com.yahoo.elide.core.datastore.DataStoreTransaction) FilterExpression(com.yahoo.elide.core.filter.expression.FilterExpression) Sorting(com.yahoo.elide.core.request.Sorting) Test(org.junit.jupiter.api.Test)

Example 7 with Sorting

use of com.yahoo.elide.core.request.Sorting in project elide by yahoo.

the class PersistentResource method loadRecords.

/**
 * Load a collection from the datastore.
 *
 * @param projection   the projection to load
 * @param requestScope the request scope
 * @param ids          a list of object identifiers to optionally load.  Can be empty.
 * @return a filtered collection of resources loaded from the datastore.
 */
public static Observable<PersistentResource> loadRecords(EntityProjection projection, List<String> ids, RequestScope requestScope) {
    Type<?> loadClass = projection.getType();
    Pagination pagination = projection.getPagination();
    Sorting sorting = projection.getSorting();
    FilterExpression filterExpression = projection.getFilterExpression();
    EntityDictionary dictionary = requestScope.getDictionary();
    DataStoreTransaction tx = requestScope.getTransaction();
    if (shouldSkipCollection(loadClass, ReadPermission.class, requestScope, projection.getRequestedFields())) {
        if (ids.isEmpty()) {
            return Observable.empty();
        }
        throw new InvalidObjectIdentifierException(ids.toString(), dictionary.getJsonAliasFor(loadClass));
    }
    Set<String> requestedFields = projection.getRequestedFields();
    if (pagination != null && !pagination.isDefaultInstance() && !CanPaginateVisitor.canPaginate(loadClass, dictionary, requestScope, requestedFields)) {
        throw new BadRequestException(String.format("Cannot paginate %s", dictionary.getJsonAliasFor(loadClass)));
    }
    Set<PersistentResource> newResources = new LinkedHashSet<>();
    if (!ids.isEmpty()) {
        String typeAlias = dictionary.getJsonAliasFor(loadClass);
        newResources = requestScope.getNewPersistentResources().stream().filter(resource -> typeAlias.equals(resource.getTypeName()) && ids.contains(resource.getUUID().orElse(""))).collect(Collectors.toSet());
        FilterExpression idExpression = buildIdFilterExpression(ids, loadClass, dictionary, requestScope);
        // Combine filters if necessary
        filterExpression = Optional.ofNullable(filterExpression).map(fe -> (FilterExpression) new AndFilterExpression(idExpression, fe)).orElse(idExpression);
    }
    Optional<FilterExpression> permissionFilter = getPermissionFilterExpression(loadClass, requestScope, requestedFields);
    if (permissionFilter.isPresent()) {
        if (filterExpression != null) {
            filterExpression = new AndFilterExpression(filterExpression, permissionFilter.get());
        } else {
            filterExpression = permissionFilter.get();
        }
    }
    EntityProjection modifiedProjection = projection.copyOf().filterExpression(filterExpression).sorting(sorting).pagination(pagination).build();
    Observable<PersistentResource> existingResources = filter(ReadPermission.class, Optional.ofNullable(modifiedProjection.getFilterExpression()), projection.getRequestedFields(), Observable.fromIterable(new PersistentResourceSet(tx.loadObjects(modifiedProjection, requestScope), requestScope)));
    // TODO: Sort again in memory now that two sets are glommed together?
    Observable<PersistentResource> allResources = Observable.fromIterable(newResources).mergeWith(existingResources);
    Set<String> foundIds = new HashSet<>();
    allResources = allResources.doOnNext((resource) -> {
        String id = (String) resource.getUUID().orElseGet(resource::getId);
        if (ids.contains(id)) {
            foundIds.add(id);
        }
    });
    allResources = allResources.doOnComplete(() -> {
        Set<String> missedIds = Sets.difference(new HashSet<>(ids), foundIds);
        if (!missedIds.isEmpty()) {
            throw new InvalidObjectIdentifierException(missedIds.toString(), dictionary.getJsonAliasFor(loadClass));
        }
    });
    return allResources;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) Resource(com.yahoo.elide.jsonapi.models.Resource) Data(com.yahoo.elide.jsonapi.models.Data) StringUtils(org.apache.commons.lang3.StringUtils) UpdatePermission(com.yahoo.elide.annotation.UpdatePermission) ClassType(com.yahoo.elide.core.type.ClassType) DeletePermission(com.yahoo.elide.annotation.DeletePermission) Argument(com.yahoo.elide.core.request.Argument) InvalidSyntaxException(com.yahoo.elide.core.audit.InvalidSyntaxException) Map(java.util.Map) DataStoreIterable(com.yahoo.elide.core.datastore.DataStoreIterable) LifeCycleHookBinding(com.yahoo.elide.annotation.LifeCycleHookBinding) EntityBinding(com.yahoo.elide.core.dictionary.EntityBinding) NonNull(lombok.NonNull) Collection(java.util.Collection) Set(java.util.Set) CoerceUtil(com.yahoo.elide.core.utils.coerce.CoerceUtil) Collectors(java.util.stream.Collectors) EntityDictionary(com.yahoo.elide.core.dictionary.EntityDictionary) Sets(com.google.common.collect.Sets) Serializable(java.io.Serializable) Objects(java.util.Objects) ExpressionResult(com.yahoo.elide.core.security.permissions.ExpressionResult) List(java.util.List) Annotation(java.lang.annotation.Annotation) AndFilterExpression(com.yahoo.elide.core.filter.expression.AndFilterExpression) Optional(java.util.Optional) RelationshipType(com.yahoo.elide.core.dictionary.RelationshipType) Attribute(com.yahoo.elide.core.request.Attribute) InvalidAttributeException(com.yahoo.elide.core.exceptions.InvalidAttributeException) Function(java.util.function.Function) Supplier(java.util.function.Supplier) CollectionUtils(org.apache.commons.collections4.CollectionUtils) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) IterableUtils(org.apache.commons.collections4.IterableUtils) LogMessageImpl(com.yahoo.elide.core.audit.LogMessageImpl) DELETE(com.yahoo.elide.annotation.LifeCycleHookBinding.Operation.DELETE) EntityDictionary.getType(com.yahoo.elide.core.dictionary.EntityDictionary.getType) JsonIgnore(com.fasterxml.jackson.annotation.JsonIgnore) Predicates(com.google.common.base.Predicates) InternalServerErrorException(com.yahoo.elide.core.exceptions.InternalServerErrorException) CanPaginateVisitor(com.yahoo.elide.core.security.visitors.CanPaginateVisitor) Observable(io.reactivex.Observable) LogMessage(com.yahoo.elide.core.audit.LogMessage) FilterExpression(com.yahoo.elide.core.filter.expression.FilterExpression) LinkedHashSet(java.util.LinkedHashSet) UPDATE(com.yahoo.elide.annotation.LifeCycleHookBinding.Operation.UPDATE) DataStoreTransaction(com.yahoo.elide.core.datastore.DataStoreTransaction) VerifyFieldAccessFilterExpressionVisitor(com.yahoo.elide.core.filter.visitors.VerifyFieldAccessFilterExpressionVisitor) ChangeSpec(com.yahoo.elide.core.security.ChangeSpec) COLLECTION_TYPE(com.yahoo.elide.core.type.ClassType.COLLECTION_TYPE) Sorting(com.yahoo.elide.core.request.Sorting) InvalidEntityBodyException(com.yahoo.elide.core.exceptions.InvalidEntityBodyException) InvalidObjectIdentifierException(com.yahoo.elide.core.exceptions.InvalidObjectIdentifierException) InPredicate(com.yahoo.elide.core.filter.predicates.InPredicate) EntityProjection(com.yahoo.elide.core.request.EntityProjection) Relationship(com.yahoo.elide.jsonapi.models.Relationship) ForbiddenAccessException(com.yahoo.elide.core.exceptions.ForbiddenAccessException) ReadPermission(com.yahoo.elide.annotation.ReadPermission) BadRequestException(com.yahoo.elide.core.exceptions.BadRequestException) Pagination(com.yahoo.elide.core.request.Pagination) ResourceIdentifier(com.yahoo.elide.jsonapi.models.ResourceIdentifier) TreeMap(java.util.TreeMap) CreatePermission(com.yahoo.elide.annotation.CreatePermission) CREATE(com.yahoo.elide.annotation.LifeCycleHookBinding.Operation.CREATE) Type(com.yahoo.elide.core.type.Type) Preconditions(com.google.common.base.Preconditions) Comparator(java.util.Comparator) Collections(java.util.Collections) EMPTY_BINDING(com.yahoo.elide.core.dictionary.EntityBinding.EMPTY_BINDING) Audit(com.yahoo.elide.annotation.Audit) NonTransferable(com.yahoo.elide.annotation.NonTransferable) EntityProjection(com.yahoo.elide.core.request.EntityProjection) Set(java.util.Set) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) Sorting(com.yahoo.elide.core.request.Sorting) Pagination(com.yahoo.elide.core.request.Pagination) DataStoreTransaction(com.yahoo.elide.core.datastore.DataStoreTransaction) BadRequestException(com.yahoo.elide.core.exceptions.BadRequestException) InvalidObjectIdentifierException(com.yahoo.elide.core.exceptions.InvalidObjectIdentifierException) AndFilterExpression(com.yahoo.elide.core.filter.expression.AndFilterExpression) FilterExpression(com.yahoo.elide.core.filter.expression.FilterExpression) EntityDictionary(com.yahoo.elide.core.dictionary.EntityDictionary) AndFilterExpression(com.yahoo.elide.core.filter.expression.AndFilterExpression) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Example 8 with Sorting

use of com.yahoo.elide.core.request.Sorting in project elide by yahoo.

the class InMemoryStoreTransaction method fetchData.

private DataStoreIterable<Object> fetchData(DataFetcher fetcher, EntityProjection projection, boolean filterInMemory, RequestScope scope) {
    Optional<FilterExpression> filterExpression = Optional.ofNullable(projection.getFilterExpression());
    Pair<Optional<FilterExpression>, Optional<FilterExpression>> expressionSplit = splitFilterExpression(scope, projection, filterInMemory);
    Optional<FilterExpression> dataStoreFilter = expressionSplit.getLeft();
    Optional<FilterExpression> inMemoryFilter = expressionSplit.getRight();
    Optional<Sorting> dataStoreSorting = getDataStoreSorting(scope, projection, filterInMemory);
    boolean sortingInMemory = dataStoreSorting.isEmpty() && projection.getSorting() != null;
    Optional<Pagination> dataStorePagination = inMemoryFilter.isPresent() || sortingInMemory ? Optional.empty() : Optional.ofNullable(projection.getPagination());
    DataStoreIterable<Object> loadedRecords = fetcher.fetch(dataStoreFilter, dataStoreSorting, dataStorePagination, scope);
    if (loadedRecords == null) {
        return new DataStoreIterableBuilder().build();
    }
    if (inMemoryFilter.isPresent() || (loadedRecords.needsInMemoryFilter() && projection.getFilterExpression() != null)) {
        loadedRecords = filterLoadedData(loadedRecords, filterExpression, scope);
    }
    return sortAndPaginateLoadedData(loadedRecords, sortingInMemory, projection.getSorting(), projection.getPagination(), scope);
}
Also used : Pagination(com.yahoo.elide.core.request.Pagination) Optional(java.util.Optional) DataStoreIterableBuilder(com.yahoo.elide.core.datastore.DataStoreIterableBuilder) FilterExpression(com.yahoo.elide.core.filter.expression.FilterExpression) Sorting(com.yahoo.elide.core.request.Sorting)

Example 9 with Sorting

use of com.yahoo.elide.core.request.Sorting in project elide by yahoo.

the class InMemoryStoreTransactionTest method testSortOnComputedAttribute.

@Test
public void testSortOnComputedAttribute() {
    Map<String, Sorting.SortOrder> sortOrder = new HashMap<>();
    sortOrder.put("fullName", Sorting.SortOrder.desc);
    Editor editor1 = new Editor();
    editor1.setFirstName("A");
    editor1.setLastName("X");
    Editor editor2 = new Editor();
    editor2.setFirstName("B");
    editor2.setLastName("Y");
    Sorting sorting = new SortingImpl(sortOrder, Editor.class, dictionary);
    EntityProjection projection = EntityProjection.builder().type(Editor.class).sorting(sorting).build();
    DataStoreIterable iterable = new DataStoreIterableBuilder(Arrays.asList(editor1, editor2)).sortInMemory(false).build();
    ArgumentCaptor<EntityProjection> projectionArgument = ArgumentCaptor.forClass(EntityProjection.class);
    when(wrappedTransaction.loadObjects(projectionArgument.capture(), eq(scope))).thenReturn(iterable);
    Collection<Object> loaded = Lists.newArrayList(inMemoryStoreTransaction.loadObjects(projection, scope));
    assertNull(projectionArgument.getValue().getSorting());
    assertEquals(2, loaded.size());
    Object[] sorted = loaded.toArray();
    assertEquals(editor2, sorted[0]);
    assertEquals(editor1, sorted[1]);
}
Also used : EntityProjection(com.yahoo.elide.core.request.EntityProjection) DataStoreIterableBuilder(com.yahoo.elide.core.datastore.DataStoreIterableBuilder) HashMap(java.util.HashMap) DataStoreIterable(com.yahoo.elide.core.datastore.DataStoreIterable) Sorting(com.yahoo.elide.core.request.Sorting) SortingImpl(com.yahoo.elide.core.sort.SortingImpl) Editor(example.Editor) Test(org.junit.jupiter.api.Test)

Example 10 with Sorting

use of com.yahoo.elide.core.request.Sorting in project elide by yahoo.

the class InMemoryStoreTransactionTest method testFilteringRequiresInMemorySorting.

@Test
public void testFilteringRequiresInMemorySorting() {
    FilterExpression expression = new InPredicate(new Path(Book.class, dictionary, "genre"), "Literary Fiction");
    Map<String, Sorting.SortOrder> sortOrder = new HashMap<>();
    sortOrder.put("title", Sorting.SortOrder.desc);
    Sorting sorting = new SortingImpl(sortOrder, Book.class, dictionary);
    EntityProjection projection = EntityProjection.builder().type(Book.class).filterExpression(expression).sorting(sorting).build();
    DataStoreIterable filterInMemory = new DataStoreIterableBuilder(books).filterInMemory(true).build();
    when(wrappedTransaction.loadObjects(any(), eq(scope))).thenReturn(filterInMemory);
    Collection<Object> loaded = Lists.newArrayList(inMemoryStoreTransaction.loadObjects(projection, scope));
    verify(wrappedTransaction, times(1)).loadObjects(any(EntityProjection.class), eq(scope));
    assertEquals(2, loaded.size());
    List<String> bookTitles = loaded.stream().map((o) -> ((Book) o).getTitle()).collect(Collectors.toList());
    assertEquals(Lists.newArrayList("Book 3", "Book 1"), bookTitles);
}
Also used : Path(com.yahoo.elide.core.Path) BeforeEach(org.junit.jupiter.api.BeforeEach) Arrays(java.util.Arrays) Path(com.yahoo.elide.core.Path) DataStoreIterableBuilder(com.yahoo.elide.core.datastore.DataStoreIterableBuilder) ArgumentMatchers.eq(org.mockito.ArgumentMatchers.eq) Publisher(example.Publisher) SortingImpl(com.yahoo.elide.core.sort.SortingImpl) ClassType(com.yahoo.elide.core.type.ClassType) Map(java.util.Map) PersistentResource(com.yahoo.elide.core.PersistentResource) DataStoreIterable(com.yahoo.elide.core.datastore.DataStoreIterable) Relationship(com.yahoo.elide.core.request.Relationship) RequestScope(com.yahoo.elide.core.RequestScope) ImmutableSet(com.google.common.collect.ImmutableSet) DefaultClassScanner(com.yahoo.elide.core.utils.DefaultClassScanner) Collection(java.util.Collection) Collectors(java.util.stream.Collectors) EntityDictionary(com.yahoo.elide.core.dictionary.EntityDictionary) Sets(com.google.common.collect.Sets) Test(org.junit.jupiter.api.Test) List(java.util.List) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) Mockito.mock(org.mockito.Mockito.mock) ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) ElideSettingsBuilder(com.yahoo.elide.ElideSettingsBuilder) Assertions.assertNull(org.junit.jupiter.api.Assertions.assertNull) PaginationImpl(com.yahoo.elide.core.pagination.PaginationImpl) HashMap(java.util.HashMap) Author(example.Author) ArrayList(java.util.ArrayList) Lists(com.google.common.collect.Lists) Editor(example.Editor) ArgumentCaptor(org.mockito.ArgumentCaptor) ImmutableList(com.google.common.collect.ImmutableList) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) FilterExpression(com.yahoo.elide.core.filter.expression.FilterExpression) LinkedHashSet(java.util.LinkedHashSet) ElideSettings(com.yahoo.elide.ElideSettings) Price(example.Price) DataStoreTransaction(com.yahoo.elide.core.datastore.DataStoreTransaction) Sorting(com.yahoo.elide.core.request.Sorting) InPredicate(com.yahoo.elide.core.filter.predicates.InPredicate) Mockito.times(org.mockito.Mockito.times) EntityProjection(com.yahoo.elide.core.request.EntityProjection) Book(example.Book) Mockito.when(org.mockito.Mockito.when) Mockito.verify(org.mockito.Mockito.verify) Address(example.Address) Mockito.reset(org.mockito.Mockito.reset) EntityProjection(com.yahoo.elide.core.request.EntityProjection) DataStoreIterableBuilder(com.yahoo.elide.core.datastore.DataStoreIterableBuilder) HashMap(java.util.HashMap) InPredicate(com.yahoo.elide.core.filter.predicates.InPredicate) DataStoreIterable(com.yahoo.elide.core.datastore.DataStoreIterable) Sorting(com.yahoo.elide.core.request.Sorting) SortingImpl(com.yahoo.elide.core.sort.SortingImpl) Book(example.Book) FilterExpression(com.yahoo.elide.core.filter.expression.FilterExpression) Test(org.junit.jupiter.api.Test)

Aggregations

Sorting (com.yahoo.elide.core.request.Sorting)22 Test (org.junit.jupiter.api.Test)13 FilterExpression (com.yahoo.elide.core.filter.expression.FilterExpression)12 EntityProjection (com.yahoo.elide.core.request.EntityProjection)11 DataStoreIterable (com.yahoo.elide.core.datastore.DataStoreIterable)10 SortingImpl (com.yahoo.elide.core.sort.SortingImpl)10 HashMap (java.util.HashMap)10 DataStoreTransaction (com.yahoo.elide.core.datastore.DataStoreTransaction)9 Path (com.yahoo.elide.core.Path)8 DataStoreIterableBuilder (com.yahoo.elide.core.datastore.DataStoreIterableBuilder)8 Collection (java.util.Collection)7 EntityDictionary (com.yahoo.elide.core.dictionary.EntityDictionary)6 ClassType (com.yahoo.elide.core.type.ClassType)6 Map (java.util.Map)6 RequestScope (com.yahoo.elide.core.RequestScope)5 InPredicate (com.yahoo.elide.core.filter.predicates.InPredicate)5 PaginationImpl (com.yahoo.elide.core.pagination.PaginationImpl)5 Pagination (com.yahoo.elide.core.request.Pagination)5 Book (example.Book)5 Editor (example.Editor)5