Search in sources :

Example 21 with Snapshot

use of org.opencastproject.assetmanager.api.Snapshot in project opencast by opencast.

the class AssetManagerTestBase method mkAbstractAssetManager.

/**
 * Create a new test asset manager.
 */
protected AbstractAssetManager mkAbstractAssetManager() throws Exception {
    penv = PersistenceEnvs.mkTestEnvFromSystemProperties(PERSISTENCE_UNIT);
    // empty database
    penv.tx(new Fn<EntityManager, Object>() {

        @Override
        public Object apply(EntityManager entityManager) {
            Queries.sql.update(entityManager, "delete from oc_assets_asset");
            Queries.sql.update(entityManager, "delete from oc_assets_properties");
            Queries.sql.update(entityManager, "delete from oc_assets_snapshot");
            Queries.sql.update(entityManager, "delete from oc_assets_version_claim");
            return null;
        }
    });
    final Database db = new Database(penv);
    // 
    final Workspace workspace = EasyMock.createNiceMock(Workspace.class);
    EasyMock.expect(workspace.get(EasyMock.anyObject(URI.class))).andReturn(IoSupport.classPathResourceAsFile("/dublincore-a.xml").get()).anyTimes();
    EasyMock.expect(workspace.get(EasyMock.anyObject(URI.class), EasyMock.anyBoolean())).andAnswer(() -> {
        File tmp = tempFolder.newFile();
        FileUtils.copyFile(new File(getClass().getResource("/dublincore-a.xml").toURI()), tmp);
        return tmp;
    }).anyTimes();
    EasyMock.replay(workspace);
    // 
    final AssetStore assetStore = mkAssetStore();
    // 
    return new AbstractAssetManager() {

        @Override
        public Database getDb() {
            return db;
        }

        @Override
        public AssetStore getAssetStore() {
            return assetStore;
        }

        @Override
        public HttpAssetProvider getHttpAssetProvider() {
            // identity provider
            return new HttpAssetProvider() {

                @Override
                public Snapshot prepareForDelivery(Snapshot snapshot) {
                    return snapshot;
                }
            };
        }

        @Override
        protected Workspace getWorkspace() {
            return workspace;
        }

        @Override
        protected String getCurrentOrgId() {
            return AssetManagerTestBase.this.getCurrentOrgId();
        }
    };
}
Also used : Snapshot(org.opencastproject.assetmanager.api.Snapshot) EntityManager(javax.persistence.EntityManager) Database(org.opencastproject.assetmanager.impl.persistence.Database) AssetStore(org.opencastproject.assetmanager.impl.storage.AssetStore) File(java.io.File) Workspace(org.opencastproject.workspace.api.Workspace)

Example 22 with Snapshot

use of org.opencastproject.assetmanager.api.Snapshot 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);
}
Also used : Set(java.util.Set) HashMap(java.util.HashMap) Fn2(com.entwinemedia.fn.Fn2) BooleanExpression(com.mysema.query.types.expr.BooleanExpression) Opt(com.entwinemedia.fn.data.Opt) List(java.util.List) Property(org.opencastproject.assetmanager.api.Property) EntityPath(com.mysema.query.types.EntityPath) Fn(com.entwinemedia.fn.Fn) JPAQuery(com.mysema.query.jpa.impl.JPAQuery) Snapshot(org.opencastproject.assetmanager.api.Snapshot) BooleanExpression(com.mysema.query.types.expr.BooleanExpression) Expression(com.mysema.query.types.Expression) HashMap(java.util.HashMap) Map(java.util.Map)

Example 23 with Snapshot

use of org.opencastproject.assetmanager.api.Snapshot in project opencast by opencast.

the class TestTasksEndpoint method mkAssetManager.

AssetManager mkAssetManager(final Workspace workspace) throws Exception {
    final PersistenceEnv penv = PersistenceEnvs.mk(mkEntityManagerFactory("org.opencastproject.assetmanager.impl"));
    final Database db = new Database(penv);
    return new AbstractAssetManager() {

        @Override
        public HttpAssetProvider getHttpAssetProvider() {
            // identity provider
            return new HttpAssetProvider() {

                @Override
                public Snapshot prepareForDelivery(Snapshot snapshot) {
                    return snapshot;
                }
            };
        }

        @Override
        public Database getDb() {
            return db;
        }

        @Override
        protected Workspace getWorkspace() {
            return workspace;
        }

        @Override
        public AssetStore getAssetStore() {
            return mkAssetStore(workspace);
        }

        @Override
        protected String getCurrentOrgId() {
            return DefaultOrganization.DEFAULT_ORGANIZATION_ID;
        }
    };
}
Also used : Snapshot(org.opencastproject.assetmanager.api.Snapshot) HttpAssetProvider(org.opencastproject.assetmanager.impl.HttpAssetProvider) AbstractAssetManager(org.opencastproject.assetmanager.impl.AbstractAssetManager) PersistenceEnv(org.opencastproject.util.persistencefn.PersistenceEnv) Database(org.opencastproject.assetmanager.impl.persistence.Database)

Example 24 with Snapshot

use of org.opencastproject.assetmanager.api.Snapshot in project opencast by opencast.

the class AssetManagerWithSecurity method takeSnapshot.

@Override
public Snapshot takeSnapshot(String owner, MediaPackage mp) {
    if (isAuthorizedByAcl(mp, WRITE_ACTION)) {
        final Snapshot snapshot = super.takeSnapshot(owner, mp);
        final AccessControlList acl = authSvc.getActiveAcl(mp).getA();
        storeAclAsProperties(snapshot, acl);
        return snapshot;
    } else {
        return chuck(new UnauthorizedException("Not allowed to take snapshot of media package " + mp.getIdentifier().toString()));
    }
}
Also used : AccessControlList(org.opencastproject.security.api.AccessControlList) Snapshot(org.opencastproject.assetmanager.api.Snapshot) UnauthorizedException(org.opencastproject.security.api.UnauthorizedException)

Example 25 with Snapshot

use of org.opencastproject.assetmanager.api.Snapshot in project opencast by opencast.

the class AssetManagerUpdatedEventHandler method handleEvent.

public void handleEvent(final SeriesItem seriesItem) {
    // A series or its ACL has been updated. Find any mediapackages with that series, and update them.
    logger.debug("Handling {}", seriesItem);
    String seriesId = seriesItem.getSeriesId();
    // We must be an administrative user to make this query
    final User prevUser = securityService.getUser();
    final Organization prevOrg = securityService.getOrganization();
    try {
        securityService.setUser(SecurityUtil.createSystemUser(systemAccount, prevOrg));
        final AQueryBuilder q = assetManager.createQuery();
        final AResult result = q.select(q.snapshot()).where(q.seriesId().eq(seriesId).and(q.version().isLatest())).run();
        for (Snapshot snapshot : enrich(result).getSnapshots()) {
            final String orgId = snapshot.getOrganizationId();
            final Organization organization = organizationDirectoryService.getOrganization(orgId);
            if (organization == null) {
                logger.warn("Skipping update of episode {} since organization {} is unknown", snapshot.getMediaPackage().getIdentifier().compact(), orgId);
                continue;
            }
            securityService.setOrganization(organization);
            MediaPackage mp = snapshot.getMediaPackage();
            // Update the series XACML file
            if (SeriesItem.Type.UpdateAcl.equals(seriesItem.getType())) {
                // Build a new XACML file for this mediapackage
                authorizationService.setAcl(mp, AclScope.Series, seriesItem.getAcl());
            }
            // Update the series dublin core or extended metadata
            if (SeriesItem.Type.UpdateCatalog.equals(seriesItem.getType()) || SeriesItem.Type.UpdateElement.equals(seriesItem.getType())) {
                DublinCoreCatalog seriesDublinCore = null;
                MediaPackageElementFlavor catalogType = null;
                if (SeriesItem.Type.UpdateCatalog.equals(seriesItem.getType())) {
                    seriesDublinCore = seriesItem.getMetadata();
                    mp.setSeriesTitle(seriesDublinCore.getFirst(DublinCore.PROPERTY_TITLE));
                    catalogType = MediaPackageElements.SERIES;
                } else {
                    seriesDublinCore = seriesItem.getExtendedMetadata();
                    catalogType = MediaPackageElementFlavor.flavor(seriesItem.getElementType(), "series");
                }
                // Update the series dublin core
                Catalog[] seriesCatalogs = mp.getCatalogs(catalogType);
                if (seriesCatalogs.length == 1) {
                    Catalog c = seriesCatalogs[0];
                    String filename = FilenameUtils.getName(c.getURI().toString());
                    URI uri = workspace.put(mp.getIdentifier().toString(), c.getIdentifier(), filename, dublinCoreService.serialize(seriesDublinCore));
                    c.setURI(uri);
                    // setting the URI to a new source so the checksum will most like be invalid
                    c.setChecksum(null);
                }
            }
            // Remove the series catalogs and isPartOf from episode catalog
            if (SeriesItem.Type.Delete.equals(seriesItem.getType())) {
                mp.setSeries(null);
                mp.setSeriesTitle(null);
                for (Catalog seriesCatalog : mp.getCatalogs(MediaPackageElements.SERIES)) {
                    mp.remove(seriesCatalog);
                }
                authorizationService.removeAcl(mp, AclScope.Series);
                for (Catalog episodeCatalog : mp.getCatalogs(MediaPackageElements.EPISODE)) {
                    DublinCoreCatalog episodeDublinCore = DublinCoreUtil.loadDublinCore(workspace, episodeCatalog);
                    episodeDublinCore.remove(DublinCore.PROPERTY_IS_PART_OF);
                    String filename = FilenameUtils.getName(episodeCatalog.getURI().toString());
                    URI uri = workspace.put(mp.getIdentifier().toString(), episodeCatalog.getIdentifier(), filename, dublinCoreService.serialize(episodeDublinCore));
                    episodeCatalog.setURI(uri);
                    // setting the URI to a new source so the checksum will most like be invalid
                    episodeCatalog.setChecksum(null);
                }
                // here we don't know the series extended metadata types,
                // we assume that all series catalog flavors have a fixed subtype: series
                MediaPackageElementFlavor seriesFlavor = MediaPackageElementFlavor.flavor("*", "series");
                for (Catalog catalog : mp.getCatalogs()) {
                    if (catalog.getFlavor().matches(seriesFlavor))
                        mp.remove(catalog);
                }
            }
            try {
                // Update the asset manager with the modified mediapackage
                assetManager.takeSnapshot(snapshot.getOwner(), mp);
            } catch (AssetManagerException e) {
                logger.error("Error updating mediapackage {}", mp.getIdentifier().compact(), e);
            }
        }
    } catch (NotFoundException e) {
        logger.warn(e.getMessage());
    } catch (IOException e) {
        logger.warn(e.getMessage());
    } finally {
        securityService.setOrganization(prevOrg);
        securityService.setUser(prevUser);
    }
}
Also used : User(org.opencastproject.security.api.User) Organization(org.opencastproject.security.api.Organization) AQueryBuilder(org.opencastproject.assetmanager.api.query.AQueryBuilder) NotFoundException(org.opencastproject.util.NotFoundException) AssetManagerException(org.opencastproject.assetmanager.api.AssetManagerException) IOException(java.io.IOException) MediaPackageElementFlavor(org.opencastproject.mediapackage.MediaPackageElementFlavor) URI(java.net.URI) Catalog(org.opencastproject.mediapackage.Catalog) DublinCoreCatalog(org.opencastproject.metadata.dublincore.DublinCoreCatalog) Snapshot(org.opencastproject.assetmanager.api.Snapshot) MediaPackage(org.opencastproject.mediapackage.MediaPackage) AResult(org.opencastproject.assetmanager.api.query.AResult) DublinCoreCatalog(org.opencastproject.metadata.dublincore.DublinCoreCatalog)

Aggregations

Snapshot (org.opencastproject.assetmanager.api.Snapshot)26 Test (org.junit.Test)11 MediaPackage (org.opencastproject.mediapackage.MediaPackage)10 AQueryBuilder (org.opencastproject.assetmanager.api.query.AQueryBuilder)9 AResult (org.opencastproject.assetmanager.api.query.AResult)7 URI (java.net.URI)6 Set (java.util.Set)5 ARecord (org.opencastproject.assetmanager.api.query.ARecord)5 ASelectQuery (org.opencastproject.assetmanager.api.query.ASelectQuery)5 Parameters (junitparams.Parameters)4 Version (org.opencastproject.assetmanager.api.Version)4 Predicate (org.opencastproject.assetmanager.api.query.Predicate)4 Unit (com.entwinemedia.fn.Unit)3 Target (org.opencastproject.assetmanager.api.query.Target)3 VersionField (org.opencastproject.assetmanager.api.query.VersionField)3 Database (org.opencastproject.assetmanager.impl.persistence.Database)3 Job (org.opencastproject.job.api.Job)3 DublinCoreCatalog (org.opencastproject.metadata.dublincore.DublinCoreCatalog)3 ArrayList (java.util.ArrayList)2 Date (java.util.Date)2