use of org.opencastproject.assetmanager.api.Property in project opencast by opencast.
the class DuplicateEventWorkflowOperationHandler method copyProperties.
private void copyProperties(String namespace, MediaPackage source, MediaPackage destination) {
final AQueryBuilder q = assetManager.createQuery();
final AResult properties = q.select(q.propertiesOf(namespace)).where(q.mediaPackageId(source.getIdentifier().toString())).run();
if (properties.getRecords().head().isNone()) {
logger.info("No properties to copy for media package {}.", source.getIdentifier(), namespace);
return;
}
for (final Property p : properties.getRecords().head().get().getProperties()) {
final PropertyId newPropId = PropertyId.mk(destination.getIdentifier().toString(), namespace, p.getId().getName());
assetManager.setProperty(Property.mk(newPropId, p.getValue()));
}
}
use of org.opencastproject.assetmanager.api.Property in project opencast by opencast.
the class AbstractAssetManagerPropertyRetrievalTest method testPropertyRetrieval.
/**
* Create some media packages and associate some random properties to each of them.
* Then iterate all created properties and create a query for each of them.
*/
@Test
@Parameters
public void testPropertyRetrieval(final Params params) {
// create a set of media packages and add them to the asset manager
final String[] mps = createAndAddMediaPackagesSimple(params.mpCount, 1, 1);
final Random random = new Random(System.nanoTime());
// create a set of random property names
final PropertyName[] propertyNames = createRandomPropertyNames(params.propertyNameSetSize);
// create a random amount of random properties for each media package
final Stream<Property> props = $(mps).bind(new Fn<String, Stream<Property>>() {
@Override
public Stream<Property> apply(final String mp) {
// create a random amount of random properties
return Stream.cont(inc()).take(random.nextInt(params.maxProps - params.minProps + 1) + params.minProps).map(new Fn<Integer, Property>() {
@Override
public Property apply(Integer ignore) {
// try to pick a free property a 100 times
for (int i = 0; i < 100; i++) {
// randomly select a property name
final PropertyName pName = propertyNames[random.nextInt(propertyNames.length)];
// check if the selected property is already associated with the current media package
final ASelectQuery doesPropertyExist = q.select(q.properties(pName)).where(q.mediaPackageId(mp));
if (sizeOf(doesPropertyExist.run().getRecords().bind(ARecords.getProperties)) == 0) {
// create a property with a randomly picked value
final Property p = Property.mk(PropertyId.mk(mp, pName), params.values[random.nextInt(params.values.length)]);
if (am.setProperty(p))
return p;
}
}
fail("Cannot pick another random property that has not been inserted yet");
return null;
}
});
}
}).eval();
assertThat("Number of generated properties", sizeOf(props), allOf(greaterThanOrEqualTo(params.mpCount * params.minProps), lessThanOrEqualTo(params.mpCount * params.maxProps)));
// iterate all properties and try to retrieve them from the AssetManager
for (final Property prop : props) {
final AResult r = q.select(params.mkTarget.apply(prop)).where(params.mkWhere.apply(prop)).run();
// get all properties of the result records
assertThat("Number of records", r.getSize(), params.expectRecords);
final Stream<Property> allProps = r.getRecords().bind(ARecords.getProperties);
assertThat("Total number of properties: " + allProps.mkString(", "), sizeOf(allProps), params.expectPropertiesTotal);
assertThat("Total number of snapshots", sizeOf(r.getRecords().bind(ARecords.getSnapshot)), params.expectSnapshotsTotal);
final Stream<Property> findSavedProperty = r.getRecords().bind(ARecords.getProperties).filter(Booleans.eq(prop));
if (params.expectContainsSavedProperty) {
assertThat("Contains saved property", findSavedProperty, hasItem(prop));
}
}
}
use of org.opencastproject.assetmanager.api.Property in project opencast by opencast.
the class AbstractASelectQuery method run.
private AResult run(JPAQueryFactory f) {
// run query and map the result to records
final long startTime = System.nanoTime();
// resolve AST
final SelectQueryContribution r = contributeSelect(f);
final boolean toFetchProperties = r.fetch.exists(Booleans.<Expression<?>>eq(QPropertyDto.propertyDto));
// # create Querydsl query
final JPAQuery q = f.query();
// # from
{
// Make sure that the snapshotDto is always contained in the from clause because the media package ID and
// the ID are always selected.
// Use a mutable hash set to be able to use the removeAll operation.
final Set<EntityPath<?>> from = Stream.<EntityPath<?>>mk(Q_SNAPSHOT).append(// all collected from clauses
r.from).append(// all from clauses from the joins
r.join.map(Join.getFrom)).toSet(SetB.MH);
// Now remove everything that will be joined. Adding them in both the from and a join
// clause is not allowed.
from.removeAll(r.join.map(Join.getJoin).toSet());
q.from(JpaFns.toEntityPathArray(from));
}
// # join
if (!r.join.isEmpty()) {
// Group joins by entity and combine all "on" clauses with "or" expressions.
// This way there is only one join clause per distinct entity which eliminates the need to alias entities
// like this `new QPropertyDto("alias")`.
// Entity aliasing produces many issues which seem to cause a huge rewrite of the query building mechanism
// so it should be prevented at all costs.
final Map<EntityPath<?>, BooleanExpression> joins = r.join.foldl(new HashMap<EntityPath<?>, BooleanExpression>(), new Fn2<Map<EntityPath<?>, BooleanExpression>, Join, Map<EntityPath<?>, BooleanExpression>>() {
@Override
public Map<EntityPath<?>, BooleanExpression> apply(Map<EntityPath<?>, BooleanExpression> sum, Join join) {
// get the on expression saved with the join, may be null
final BooleanExpression existing = sum.get(join.join);
final BooleanExpression combined;
// combine the existing and the current expression
if (existing == null) {
combined = join.on;
} else if (existing.equals(join.on)) {
// if both expressions are equal there is no need to combine them
combined = existing;
} else {
// if different combine with logical "or"
combined = existing.or(join.on);
}
sum.put(join.join, combined);
return sum;
}
});
for (final Map.Entry<EntityPath<?>, BooleanExpression> j : joins.entrySet()) {
q.leftJoin(j.getKey()).on(j.getValue());
}
}
// # where
q.where(r.where.orNull());
// # paging
for (Integer a : r.offset) {
q.offset(a);
}
for (Integer a : r.limit) {
q.limit(a);
}
// # order
for (OrderSpecifier<?> a : r.order) {
q.orderBy(a);
}
// # distinct
if (!toFetchProperties) {
// if no properties shall be fetched the result set can be distinct
q.distinct();
}
// # fetch
// create parameters for fetch clause, i.e. Querydsl's list() method
final List<Expression<?>> fetch;
{
// check if the media package ID needs to be selected separately
if (r.fetch.exists(MandatoryFetch.exists)) {
fetch = r.fetch.toList();
} else {
fetch = r.fetch.append(MandatoryFetch.fetch).toList();
}
}
// Run the query and transform the result into records
final Stream<ARecordImpl> records;
{
// run query
am.getDb().logQuery(q);
final List<Tuple> result = q.list(JpaFns.toExpressionArray(fetch));
logger.debug("Pure query ms " + (System.nanoTime() - startTime) / 1000000);
// map result based on the fact whether properties have been fetched or not
if (!toFetchProperties) {
// No properties have been fetched -> each result row (tuple) is a distinct record (snapshot).
records = $($(result).map(toARecord(r))).map(new Fn<ARecordImpl, ARecordImpl>() {
@Override
public ARecordImpl apply(ARecordImpl record) {
Opt<Snapshot> snapshotOpt = record.getSnapshot();
Snapshot snapshot = null;
if (snapshotOpt.isSome()) {
// make sure the delivered media package has valid URIs
snapshot = am.getHttpAssetProvider().prepareForDelivery(snapshotOpt.get());
}
return new ARecordImpl(record.getSnapshotId(), record.getMediaPackageId(), record.getProperties(), snapshot);
}
});
} else {
logger.trace("Fetched properties");
// Properties have been fetched -> there may be multiple rows (tuples) per snapshot because of the join with the property table.
// Extract records and properties and link them together.
// group properties after their media package ID and make sure that no duplicate properties occur
final Map<String, Set<Property>> propertiesPerMp = $(result).bind(toProperty).foldl(new HashMap<String, Set<Property>>(), new Fn2<Map<String, Set<Property>>, Property, Map<String, Set<Property>>>() {
@Override
public Map<String, Set<Property>> apply(Map<String, Set<Property>> sum, Property p) {
final String mpId = p.getId().getMediaPackageId();
final Set<Property> props = sum.get(mpId);
if (props != null) {
props.add(p);
} else {
sum.put(mpId, SetB.MH.mk(p));
}
return sum;
}
});
// group records after their media package ID
final Map<String, List<ARecordImpl>> distinctRecords = $($(result).map(toARecord(r)).toSet()).groupMulti(ARecordImpl.getMediaPackageId);
records = $(distinctRecords.values()).bind(new Fn<List<ARecordImpl>, Iterable<ARecordImpl>>() {
@Override
public Iterable<ARecordImpl> apply(List<ARecordImpl> records) {
return $(records).map(new Fn<ARecordImpl, ARecordImpl>() {
@Override
public ARecordImpl apply(ARecordImpl record) {
final Set<Property> properties = propertiesPerMp.get(record.getMediaPackageId());
final Stream<Property> p = properties != null ? $(properties) : Stream.<Property>empty();
Snapshot snapshot = null;
Opt<Snapshot> snapshotOpt = record.getSnapshot();
if (snapshotOpt.isSome()) {
// make sure the delivered media package has valid URIs
snapshot = am.getHttpAssetProvider().prepareForDelivery(snapshotOpt.get());
}
return new ARecordImpl(record.getSnapshotId(), record.getMediaPackageId(), p, snapshot);
}
});
}
});
}
}
final long searchTime = (System.nanoTime() - startTime) / 1000000;
logger.debug("Complete query ms " + searchTime);
return new AResultImpl(AbstractASelectQuery.<ARecord>vary(records), sizeOf(records), r.offset.getOr(0), r.limit.getOr(-1), searchTime);
}
use of org.opencastproject.assetmanager.api.Property in project opencast by opencast.
the class SchedulerServiceImpl method isOptOut.
@Override
public boolean isOptOut(String mediaPackageId) throws NotFoundException, SchedulerException {
notEmpty(mediaPackageId, "mediaPackageId");
try {
AQueryBuilder query = assetManager.createQuery();
Props p = new Props(query);
Opt<Property> optOut = query.select(p.optOut().target()).where(withOrganization(query).and(query.mediaPackageId(mediaPackageId)).and(query.version().isLatest()).and(p.optOut().exists())).run().getRecords().bind(ARecords.getProperties).head();
if (optOut.isNone())
throw new NotFoundException();
return optOut.get().getValue().get(Value.BOOLEAN);
} catch (NotFoundException e) {
throw e;
} catch (Exception e) {
logger.error("Failed to get opt out status of event with mediapackage '{}': {}", mediaPackageId, getStackTrace(e));
throw new SchedulerException(e);
}
}
Aggregations