Search in sources :

Example 61 with DataStoreTransaction

use of com.yahoo.elide.core.datastore.DataStoreTransaction in project elide by yahoo.

the class MultiplexManagerTest method partialCommitFailure.

@Test
public void partialCommitFailure() throws IOException {
    final EntityDictionary entityDictionary = EntityDictionary.builder().build();
    final HashMapDataStore ds1 = new HashMapDataStore(DefaultClassScanner.getInstance(), FirstBean.class.getPackage());
    final DataStore ds2 = new TestDataStore(OtherBean.class.getPackage());
    final MultiplexManager multiplexManager = new MultiplexManager(ds1, ds2);
    multiplexManager.populateEntityDictionary(entityDictionary);
    assertEquals(ds1, multiplexManager.getSubManager(ClassType.of(FirstBean.class)));
    assertEquals(ds2, multiplexManager.getSubManager(ClassType.of(OtherBean.class)));
    try (DataStoreTransaction t = ds1.beginTransaction()) {
        assertFalse(t.loadObjects(EntityProjection.builder().type(FirstBean.class).build(), null).iterator().hasNext());
        FirstBean firstBean = FirstBean.class.newInstance();
        firstBean.setName("name");
        t.createObject(firstBean, null);
        // t.save(firstBean);
        assertFalse(t.loadObjects(EntityProjection.builder().type(FirstBean.class).build(), null).iterator().hasNext());
        t.commit(null);
    } catch (InstantiationException | IllegalAccessException e) {
        log.error("", e);
    }
    try (DataStoreTransaction t = multiplexManager.beginTransaction()) {
        FirstBean firstBean = (FirstBean) t.loadObjects(EntityProjection.builder().type(FirstBean.class).build(), null).iterator().next();
        firstBean.setName("update");
        t.save(firstBean, null);
        OtherBean otherBean = OtherBean.class.newInstance();
        t.createObject(otherBean, null);
        // t.save(firstBean);
        assertThrows(TransactionException.class, () -> t.commit(null));
    } catch (InstantiationException | IllegalAccessException e) {
        log.error("", e);
    }
    // verify state
    try (DataStoreTransaction t = ds1.beginTransaction()) {
        Iterable<Object> beans = t.loadObjects(EntityProjection.builder().type(FirstBean.class).build(), null);
        assertNotNull(beans);
        ArrayList<Object> list = Lists.newArrayList(beans.iterator());
        assertEquals(list.size(), 1);
        assertEquals(((FirstBean) list.get(0)).getName(), "name");
    }
}
Also used : OtherBean(com.yahoo.elide.example.other.OtherBean) HashMapDataStore(com.yahoo.elide.core.datastore.inmemory.HashMapDataStore) FirstBean(com.yahoo.elide.example.beans.FirstBean) HashMapDataStore(com.yahoo.elide.core.datastore.inmemory.HashMapDataStore) DataStore(com.yahoo.elide.core.datastore.DataStore) DataStoreTransaction(com.yahoo.elide.core.datastore.DataStoreTransaction) EntityDictionary(com.yahoo.elide.core.dictionary.EntityDictionary) Test(org.junit.jupiter.api.Test)

Example 62 with DataStoreTransaction

use of com.yahoo.elide.core.datastore.DataStoreTransaction in project elide by yahoo.

the class ResourceIT method testSpecialCharacterLikeQueryHQL.

@ParameterizedTest
@MethodSource("queryProviderHQL")
public void testSpecialCharacterLikeQueryHQL(FilterPredicate filterPredicate, int noOfRecords) throws Exception {
    DataStoreTransaction tx = dataStore.beginReadTransaction();
    RequestScope scope = mock(RequestScope.class);
    EntityDictionary dictionary = EntityDictionary.builder().build();
    dictionary.bindEntity(Book.class);
    when(scope.getDictionary()).thenReturn(dictionary);
    PaginationImpl pagination = mock(PaginationImpl.class);
    when(pagination.returnPageTotals()).thenReturn(true);
    tx.loadObjects(EntityProjection.builder().type(Book.class).filterExpression(filterPredicate).pagination(pagination).build(), scope);
    tx.commit(scope);
    tx.close();
    verify(pagination).setPageTotals((long) noOfRecords);
}
Also used : PaginationImpl(com.yahoo.elide.core.pagination.PaginationImpl) DataStoreTransaction(com.yahoo.elide.core.datastore.DataStoreTransaction) RequestScope(com.yahoo.elide.core.RequestScope) EntityDictionary(com.yahoo.elide.core.dictionary.EntityDictionary) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) MethodSource(org.junit.jupiter.params.provider.MethodSource)

Example 63 with DataStoreTransaction

use of com.yahoo.elide.core.datastore.DataStoreTransaction in project elide by yahoo.

the class TableExportIT method tableExportModelAdminReadPermissions.

/**
 * Tests Read Permissions on TableExport Model for Admin Role.
 * @throws IOException IOException
 */
@Test
public void tableExportModelAdminReadPermissions() throws IOException {
    ElideResponse response = null;
    String id = "edc4a871-dff2-4054-804e-d80075c08959";
    String query = "test-query";
    com.yahoo.elide.async.models.TableExport queryObj = new com.yahoo.elide.async.models.TableExport();
    queryObj.setId(id);
    queryObj.setQuery(query);
    queryObj.setResultType(ResultType.CSV);
    queryObj.setQueryType(QueryType.JSONAPI_V1_0);
    queryObj.setPrincipalName("owner-user");
    EntityDictionary dictionary = EntityDictionary.builder().checks(AsyncIntegrationTestApplicationResourceConfig.MAPPINGS).build();
    dataStore.populateEntityDictionary(dictionary);
    DataStoreTransaction tx = dataStore.beginTransaction();
    tx.createObject(queryObj, null);
    tx.commit(null);
    tx.close();
    Elide elide = new Elide(new ElideSettingsBuilder(dataStore).withEntityDictionary(dictionary).withAuditLogger(new TestAuditLogger()).build());
    User ownerUser = new User(() -> "owner-user");
    SecurityContextUser securityContextAdminUser = new SecurityContextUser(new SecurityContext() {

        @Override
        public Principal getUserPrincipal() {
            return () -> "1";
        }

        @Override
        public boolean isUserInRole(String s) {
            return true;
        }

        @Override
        public boolean isSecure() {
            return false;
        }

        @Override
        public String getAuthenticationScheme() {
            return null;
        }
    });
    SecurityContextUser securityContextNonAdminUser = new SecurityContextUser(new SecurityContext() {

        @Override
        public Principal getUserPrincipal() {
            return () -> "2";
        }

        @Override
        public boolean isUserInRole(String s) {
            return false;
        }

        @Override
        public boolean isSecure() {
            return false;
        }

        @Override
        public String getAuthenticationScheme() {
            return null;
        }
    });
    String baseUrl = "/";
    // Principal is Owner
    response = elide.get(baseUrl, "/tableExport/" + id, new MultivaluedHashMap<>(), ownerUser, NO_VERSION);
    assertEquals(HttpStatus.SC_OK, response.getResponseCode());
    // Principal has Admin Role
    response = elide.get(baseUrl, "/tableExport/" + id, new MultivaluedHashMap<>(), securityContextAdminUser, NO_VERSION);
    assertEquals(HttpStatus.SC_OK, response.getResponseCode());
    // Principal without Admin Role
    response = elide.get(baseUrl, "/tableExport/" + id, new MultivaluedHashMap<>(), securityContextNonAdminUser, NO_VERSION);
    assertEquals(HttpStatus.SC_NOT_FOUND, response.getResponseCode());
}
Also used : User(com.yahoo.elide.core.security.User) SecurityContextUser(com.yahoo.elide.jsonapi.resources.SecurityContextUser) SecurityContextUser(com.yahoo.elide.jsonapi.resources.SecurityContextUser) CoreMatchers.containsString(org.hamcrest.CoreMatchers.containsString) MultivaluedHashMap(javax.ws.rs.core.MultivaluedHashMap) ElideSettingsBuilder(com.yahoo.elide.ElideSettingsBuilder) ElideResponse(com.yahoo.elide.ElideResponse) SecurityContext(javax.ws.rs.core.SecurityContext) DataStoreTransaction(com.yahoo.elide.core.datastore.DataStoreTransaction) TestAuditLogger(com.yahoo.elide.core.audit.TestAuditLogger) Elide(com.yahoo.elide.Elide) EntityDictionary(com.yahoo.elide.core.dictionary.EntityDictionary) Principal(java.security.Principal) Test(org.junit.jupiter.api.Test)

Example 64 with DataStoreTransaction

use of com.yahoo.elide.core.datastore.DataStoreTransaction 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 65 with DataStoreTransaction

use of com.yahoo.elide.core.datastore.DataStoreTransaction in project elide by yahoo.

the class PersistentResource method loadRecord.

/**
 * Load an single entity from the DB.
 *
 * @param projection   What to load from the DB.
 * @param id           the id
 * @param requestScope the request scope
 * @param <T>          type of resource
 * @return resource persistent resource
 * @throws InvalidObjectIdentifierException the invalid object identifier exception
 */
@SuppressWarnings("resource")
@NonNull
public static <T> PersistentResource<T> loadRecord(EntityProjection projection, String id, RequestScope requestScope) throws InvalidObjectIdentifierException {
    Preconditions.checkNotNull(projection);
    Preconditions.checkNotNull(id);
    Preconditions.checkNotNull(requestScope);
    DataStoreTransaction tx = requestScope.getTransaction();
    EntityDictionary dictionary = requestScope.getDictionary();
    Type<?> loadClass = projection.getType();
    // Check the resource cache if exists
    Object obj = requestScope.getObjectById(loadClass, id);
    if (obj == null) {
        // try to load object
        Optional<FilterExpression> permissionFilter = getPermissionFilterExpression(loadClass, requestScope, projection.getRequestedFields());
        Type<?> idType = dictionary.getIdType(loadClass);
        projection = projection.copyOf().filterExpression(permissionFilter.orElse(null)).build();
        obj = tx.loadObject(projection, (Serializable) CoerceUtil.coerce(id, idType), requestScope);
        if (obj == null) {
            throw new InvalidObjectIdentifierException(id, dictionary.getJsonAliasFor(loadClass));
        }
    }
    PersistentResource<T> resource = new PersistentResource<>((T) obj, requestScope.getUUIDFor(obj), requestScope);
    // No need to have read access for a newly created object
    if (!requestScope.getNewResources().contains(resource)) {
        resource.checkFieldAwarePermissions(ReadPermission.class, projection.getRequestedFields());
    }
    return resource;
}
Also used : Serializable(java.io.Serializable) DataStoreTransaction(com.yahoo.elide.core.datastore.DataStoreTransaction) 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) NonNull(lombok.NonNull)

Aggregations

DataStoreTransaction (com.yahoo.elide.core.datastore.DataStoreTransaction)139 Test (org.junit.jupiter.api.Test)101 RequestScope (com.yahoo.elide.core.RequestScope)40 DataStore (com.yahoo.elide.core.datastore.DataStore)30 FilterExpression (com.yahoo.elide.core.filter.expression.FilterExpression)28 Elide (com.yahoo.elide.Elide)27 ElideResponse (com.yahoo.elide.ElideResponse)22 EntityProjection (com.yahoo.elide.core.request.EntityProjection)22 ArgumentMatchers.anyString (org.mockito.ArgumentMatchers.anyString)18 PersistentResource (com.yahoo.elide.core.PersistentResource)17 Item (com.yahoo.elide.datastores.search.models.Item)17 Book (example.Book)13 MultivaluedHashMap (javax.ws.rs.core.MultivaluedHashMap)9 BeforeEach (org.junit.jupiter.api.BeforeEach)9 Author (example.Author)8 FilterPredicate (com.yahoo.elide.core.filter.predicates.FilterPredicate)7 FirstBean (com.yahoo.elide.example.beans.FirstBean)7 ArrayList (java.util.ArrayList)7 HashMap (java.util.HashMap)7 AndFilterExpression (com.yahoo.elide.core.filter.expression.AndFilterExpression)6