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");
}
}
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);
}
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());
}
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;
}
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;
}
Aggregations