/**
* Licensed to The Apereo Foundation under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
*
* The Apereo Foundation licenses this file to you under the Educational
* Community License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of the License
* at:
*
* http://opensource.org/licenses/ecl2.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*
*/
package org.opencastproject.assetmanager.impl;
import static com.entwinemedia.fn.Stream.$;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.lessThanOrEqualTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.opencastproject.assetmanager.api.fn.ARecords.getProperties;
import static org.opencastproject.assetmanager.api.fn.ARecords.getSnapshot;
import static org.opencastproject.assetmanager.api.fn.Enrichments.enrich;
import org.opencastproject.assetmanager.api.Asset;
import org.opencastproject.assetmanager.api.Availability;
import org.opencastproject.assetmanager.api.Property;
import org.opencastproject.assetmanager.api.PropertyId;
import org.opencastproject.assetmanager.api.PropertyName;
import org.opencastproject.assetmanager.api.Snapshot;
import org.opencastproject.assetmanager.api.Value;
import org.opencastproject.assetmanager.api.Version;
import org.opencastproject.assetmanager.api.fn.ARecords;
import org.opencastproject.assetmanager.api.fn.Properties;
import org.opencastproject.assetmanager.api.fn.Snapshots;
import org.opencastproject.assetmanager.api.query.ARecord;
import org.opencastproject.assetmanager.api.query.AResult;
import org.opencastproject.assetmanager.api.query.Predicate;
import org.opencastproject.assetmanager.api.query.RichAResult;
import org.opencastproject.assetmanager.api.query.Target;
import org.opencastproject.mediapackage.MediaPackage;
import org.opencastproject.mediapackage.MediaPackageElement;
import org.opencastproject.mediapackage.MediaPackageSupport;
import org.opencastproject.security.api.DefaultOrganization;
import com.entwinemedia.fn.FnX;
import com.entwinemedia.fn.P2;
import com.entwinemedia.fn.Pred;
import com.entwinemedia.fn.Products;
import com.entwinemedia.fn.Stream;
import com.entwinemedia.fn.data.Opt;
import org.hamcrest.Matchers;
import org.joda.time.DateTime;
import org.junit.FixMethodOrder;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters;
import java.util.Date;
import java.util.List;
import junitparams.JUnitParamsRunner;
import junitparams.Parameters;
@RunWith(JUnitParamsRunner.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
// CHECKSTYLE:OFF
public class AbstractAssetManagerSelectTest extends AbstractAssetManagerTestBase {
@Test
public void testSelectSnapshots() throws Exception {
final MediaPackage mp = mkMediaPackage();
final MediaPackageElement mpe = mkCatalog();
mp.add(mpe);
final Snapshot snapshot = am.takeSnapshot(OWNER, mp);
final Version version = snapshot.getVersion();
assertThat("Archival date should not be in the future", snapshot.getArchivalDate(), lessThanOrEqualTo(new Date()));
assertThat("Snapshot should be available", snapshot.getAvailability(), equalTo(Availability.ONLINE));
assertThat("Snapshot should belong to the default organization",
snapshot.getOrganizationId(), equalTo(DefaultOrganization.DEFAULT_ORGANIZATION_ID));
final Opt<Asset> asset = am.getAsset(version, mp.getIdentifier().toString(), mpe.getIdentifier());
assertTrue("Asset should be found", asset.isSome());
assertEquals("Media package element part of the asset ID should equal the element's ID",
mpe.getIdentifier(), asset.get().getId().getMediaPackageElementId());
assertEquals("Mime types should equal", mpe.getMimeType(), asset.get().getMimeType().get());
assertFalse("Asset should not be found", am.getAsset(version, "id", "id").isSome());
// try to find the catalog of the media package by checksum
final MediaPackage mpCopy = MediaPackageSupport.copy(mp);
am.calcChecksumsForMediaPackageElements(AbstractAssetManager.assetsOnly(mpCopy));
assertEquals("Media package should be set up with a single catalog", 1, mpCopy.getCatalogs().length);
final String checksum = mpCopy.getCatalogs()[0].getChecksum().toString();
assertTrue("Media package element should be retrievable by checksum", am.getDb().findAssetByChecksum(checksum).isSome());
// issue some queries
{
logger.info("Run a failing query");
assertEquals("The result should not contain any records", 0,
q.select(q.snapshot())
.where(q.mediaPackageId(mp.getIdentifier().toString()).and(q.availability(Availability.ONLINE)))
.where(q.mediaPackageId("12"))
.run().getSize());
}
{
logger.info("Run query to find snapshot");
final AResult r = q.select(q.snapshot())
.where(q.mediaPackageId(mp.getIdentifier().toString()).and(q.availability(Availability.ONLINE)))
.run();
assertEquals("The result set should contain exactly one record", 1, r.getSize());
assertEquals("The media package IDs should be equal", mp.getIdentifier().toString(), r.getRecords().head2().getMediaPackageId());
assertTrue("The snapshot should be contained in the record", r.getRecords().head2().getSnapshot().isSome());
assertEquals("The media package IDs should be equal", mp.getIdentifier(), r.getRecords().head2().getSnapshot().get().getMediaPackage().getIdentifier());
}
{
final AResult r = q.select().where(q.mediaPackageId(mp.getIdentifier().toString()).and(q.availability(Availability.ONLINE))).run();
assertEquals("The result should contain one record", 1, r.getSize());
assertTrue("The result should not contain a snapshot", r.getRecords().head2().getSnapshot().isNone());
}
}
@Test
public void testSelectSnapshotByProperty() throws Exception {
final String[] mp = createAndAddMediaPackagesSimple(3, 1, 1);
am.setProperty(p.approved.mk(mp[0], true));
final RichAResult r = enrich(q.select(q.snapshot()).where(q.hasPropertiesOf(p.namespace())).run());
assertEquals("The result set should contain one record", 1, r.getSize());
assertEquals("The result set should contain one snapshot", 1, r.countSnapshots());
assertEquals("The result set should contain media package " + mp[0], mp[0], r.getSnapshots().head2().getMediaPackage().getIdentifier().toString());
}
@Test
public void testSelectSnapshotByProperties() throws Exception {
final String[] mp = createAndAddMediaPackagesSimple(3, 1, 1);
am.setProperty(p.approved.mk(mp[0], true));
am.setProperty(p.count.mk(mp[0], 1L));
final RichAResult r = enrich(q.select(q.snapshot()).where(q.hasProperties()).run());
assertEquals("The result set should contain one record", 1, r.getSize());
assertEquals("The result set should contain one snapshot", 1, r.countSnapshots());
assertEquals("The result set should contain media package " + mp[0], mp[0], r.getSnapshots().head2().getMediaPackage().getIdentifier().toString());
}
@Test
public void testSelectProperties() throws Exception {
final MediaPackage mp1 = mkMediaPackage();
final MediaPackageElement mpe = mkCatalog();
mp1.add(mpe);
am.takeSnapshot(OWNER, mp1);
//
assertEquals("No records should be found", 0, q.select(q.snapshot()).where(q.hasPropertiesOf("org.opencastproject.service")).run().getSize());
//
logger.info("Set property on first episode");
am.setProperty(Property.mk(PropertyId.mk(mp1.getIdentifier().toString(), "org.opencastproject.service", "count"), Value.mk(10L)));
assertEquals("One record should be found", 1, q.select(q.snapshot()).where(q.hasPropertiesOf("org.opencastproject.service")).run().getSize());
//
logger.info("Add another media package with some properties of the same namespace");
final MediaPackage mp2 = mkMediaPackage(mkCatalog());
am.takeSnapshot(OWNER, mp2);
am.setProperty(p.count.mk(mp2.getIdentifier().toString(), 20L));
am.setProperty(p.approved.mk(mp2.getIdentifier().toString(), true));
am.setProperty(p.start.mk(mp2.getIdentifier().toString(), new Date()));
//
logger.info("Add a 3rd media package without any properties");
am.takeSnapshot(OWNER, mkMediaPackage(mkCatalog()));
//
{
final AResult r = q.select(q.snapshot(), q.nothing()).where(p.hasPropertiesOfNamespace()).run();
assertEquals("Two records should be found", 2, r.getSize());
logger.info(r.getSearchTime() + "ms");
}
{
final AResult r = q.select(q.snapshot()).where(p.hasPropertiesOfNamespace()).run();
assertEquals("Two snapshots should be found", 2, r.getRecords().bind(getSnapshot).toList().size());
logger.info(r.getSearchTime() + "ms");
}
{
final AResult r = q.select(q.snapshot(), p.allProperties()).where(p.hasPropertiesOfNamespace()).run();
assertEquals("Two snapshots should be found", 2, r.getRecords().bind(getSnapshot).toList().size());
logger.info(r.getSearchTime() + "ms");
}
{
final AResult r = q.select(q.snapshot(), p.allProperties()).where(p.hasPropertiesOfNamespace()).run();
assertEquals("Two records with properties of the defined namespace should be found", 2, r.getSize());
logger.info(r.getSearchTime() + "ms");
}
{
final AResult r = q.select(q.snapshot(), p.allProperties()).run();
assertEquals("Three records should be found in total", 3, r.getSize());
logger.info(r.getSearchTime() + "ms");
}
{
final AResult r = q.select(q.snapshot(), p.allProperties()).where(p.count.le(5L)).run();
assertEquals("No records should be found in total", 0, r.getSize());
}
{
final AResult r = q.select(q.snapshot(), p.allProperties()).where(p.count.gt(5L)).run();
assertEquals("No records should be found in total", 2, r.getSize());
}
}
@Test
public void testSelectParticularProperties() throws Exception {
final MediaPackage mp1 = mkMediaPackage(mkCatalog());
am.takeSnapshot(OWNER, mp1);
// set some properties
am.setProperty(p.count.mk(mp1.getIdentifier().toString(), 10L));
am.setProperty(p.approved.mk(mp1.getIdentifier().toString(), true));
{
final AResult r = q.select(p.count.target()).run();
assertEquals("One record should be selected", 1, r.getSize());
assertEquals("No snapshot should be selected", 0, r.getRecords().bind(getSnapshot).toList().size());
assertEquals("One property should be selected", 1, r.getRecords().bind(getProperties).toList().size());
}
{
final AResult r = q.select(q.properties(
PropertyName.mk(p.namespace(), p.count.name().getName()),
PropertyName.mk(p.namespace(), "unkown-property"))).run();
assertEquals("One record should be selected", 1, r.getSize());
assertEquals("No snapshot should be selected", 0, r.getRecords().bind(getSnapshot).toList().size());
assertEquals("One property should be selected", 1, r.getRecords().bind(getProperties).toList().size());
}
}
@Test
public void testSelectMultipleProperties() throws Exception {
final MediaPackage mp1 = mkMediaPackage(mkCatalog());
am.takeSnapshot(OWNER, mp1);
am.setProperty(p.approved.mk(mp1.getIdentifier().toString(), true));
am.setProperty(p.count.mk(mp1.getIdentifier().toString(), 10L));
am.setProperty(p.start.mk(mp1.getIdentifier().toString(), new Date()));
assertEquals("Querying all properties, three should be found",
3, sizeOf(q.select(q.properties()).run().getRecords().bind(getProperties)));
assertEquals("Querying 'approved' and 'count', both should be found",
2, sizeOf(q.select(p.approved.target(), p.count.target())
.where(q.mediaPackageId(mp1.getIdentifier().toString()))
.run().getRecords().bind(getProperties)));
assertEquals("Querying 'approved' and 'count' in a different style, both should be found again",
2, sizeOf(q.select(q.properties(p.approved.name(), p.count.name()))
.where(q.mediaPackageId(mp1.getIdentifier().toString()))
.run().getRecords().bind(getProperties)));
logger.info("Add another media package with some properties");
final MediaPackage mp2 = mkMediaPackage(mkCatalog());
am.takeSnapshot(OWNER, mp2);
am.setProperty(p.approved.mk(mp2.getIdentifier().toString(), true));
am.setProperty(p.start.mk(mp2.getIdentifier().toString(), new Date()));
assertEquals("Querying all properties, five should be found",
5, sizeOf(q.select(q.properties()).run().getRecords().bind(getProperties)));
assertEquals("Querying target and count of the first media package, both should be found",
2, sizeOf(q.select(p.approved.target(), p.count.target())
.where(q.mediaPackageId(mp1.getIdentifier().toString()))
.run().getRecords().bind(getProperties)));
assertEquals("Querying target and count of all media packages, 3 properties should be found",
3, sizeOf(q.select(q.properties(p.approved.name(), p.count.name()))
.run().getRecords().bind(getProperties)));
}
@Test
public void testSelectMultiplePropertyNamespaces() throws Exception {
final MediaPackage mp1 = mkMediaPackage(mkCatalog());
final String mp1Id = mp1.getIdentifier().toString();
am.takeSnapshot(OWNER, mp1);
am.setProperty(p.approved.mk(mp1Id, true));
am.setProperty(p.count.mk(mp1Id, 10L));
am.setProperty(p.start.mk(mp1Id, new Date()));
//
am.setProperty(Property.mk(PropertyId.mk(mp1Id, "org.opencastproject.scheduler", "start"), Value.mk(new Date())));
am.setProperty(Property.mk(PropertyId.mk(mp1Id, "org.opencastproject.scheduler", "end"), Value.mk(new Date())));
//
{
final RichAResult r = enrich(q.select(p.allProperties(), q.propertiesOf("org.opencastproject.scheduler")).run());
assertEquals("One record should be found", 1, r.getSize());
assertEquals("All five properties should be found", 5, r.countProperties());
}
{
final RichAResult r = enrich(q.select(q.propertiesOf(p.namespace())).run());
assertEquals("One record should be found", 1, r.getSize());
assertEquals("No snapshot has been selected", 0, r.countSnapshots());
assertEquals("Three properties should be found", 3, r.countProperties());
}
{
final RichAResult r = enrich(q.select(q.propertiesOf("org.opencastproject.scheduler")).where(q.mediaPackageId(mp1Id)).run());
assertEquals(2, r.countProperties());
}
{
final RichAResult r = enrich(q.select(q.snapshot()).where(p.hasPropertiesOfNamespace()).run());
assertEquals(1, r.getSize());
}
{
final RichAResult r = enrich(q.select(p.allProperties(), q.propertiesOf("org.opencastproject.scheduler")).run());
assertEquals(1, r.getSize());
assertEquals(5, r.countProperties());
}
}
@Test
public void testSelectMultiplePropertyNamespaces_CERV_695() throws Exception {
final String[] mp = createAndAddMediaPackagesSimple(5, 1, 1);
//
logger.info("Add properties to only one of the media packages");
am.setProperty(p.approved.mk(mp[0], true));
am.setProperty(p.count.mk(mp[0], 10L));
am.setProperty(p.start.mk(mp[0], new Date()));
//
am.setProperty(Property.mk(PropertyId.mk(mp[0], "org.opencastproject.scheduler", "start"), Value.mk(new Date())));
am.setProperty(Property.mk(PropertyId.mk(mp[0], "org.opencastproject.scheduler", "end"), Value.mk(new Date())));
am.setProperty(Property.mk(PropertyId.mk(mp[0], "org.opencastproject.scheduler", "enabled"), Value.mk(true)));
//
am.setProperty(Property.mk(PropertyId.mk(mp[0], "org.opencastproject.annotation", "annotation"), Value.mk("some text")));
//
am.setProperty(Property.mk(PropertyId.mk(mp[0], "org.opencastproject.distribution", "channel"), Value.mk("engage")));
{
final RichAResult r = enrich(q.select(
q.snapshot(),
p.count.target(), p.approved.target(),
q.propertiesOf("org.opencastproject.annotation", "org.opencastproject.scheduler"),
p.legacyId.target()).run());
assertEquals("Five records should be found since there is no filtering", 5, r.getSize());
assertEquals("There should be 6 properties total", 6, r.countProperties());
assertEquals("There should be 2 properties in the 'service' namespace, 'count' and 'approved'",
2, sizeOf(r.getProperties().filter(Properties.byNamespace(p.namespace()))));
assertEquals("There should be 3 properties in the 'scheduler' namespace",
3, sizeOf(r.getProperties().filter(Properties.byNamespace("org.opencastproject.scheduler"))));
assertEquals("There should be 1 property in the 'annotation' namespace",
1, sizeOf(r.getProperties().filter(Properties.byNamespace("org.opencastproject.annotation"))));
assertEquals("There should be 5 snapshots", 5, r.countSnapshots());
assertEquals("Only one record should have properties", 1, sizeOf(r.getRecords().filter(ARecords.hasProperties)));
assertEquals("The record with properties should have media package ID " + mp[0],
mp[0], r.getRecords().filter(ARecords.hasProperties).map(ARecords.getMediaPackageId).head().get());
}
{
final RichAResult r = enrich(
q.select(
q.snapshot(),
p.count.target(),
p.approved.target(),
q.propertiesOf("org.opencastproject.annotation", "org.opencastproject.scheduler"), p.legacyId.target())
.where(
q.organizationId(DefaultOrganization.DEFAULT_ORGANIZATION_ID)
.and(q.mediaPackageId(mp[0]))
.and(q.version().isLatest()))
.run());
assertEquals("Only one record should be found since a media package predicate is given",
1, r.getSize());
}
}
@Test
public void testSelectWithMultiplePredicates_CERV_696() {
final String[] mp = createAndAddMediaPackagesSimple(2, 1, 1);
am.setProperty(p.agent.mk(mp[0], "agent-id"));
final Predicate p1 = q.organizationId(DefaultOrganization.DEFAULT_ORGANIZATION_ID).and(q.version().isLatest());
{
final RichAResult r = enrich(q.select(q.snapshot()).where(p1).run());
assertEquals("Two records should be found", 2, r.getSize());
assertEquals("Two snapshots should be contained", 2, r.countSnapshots());
assertEquals("No properties should be found since they haven't been selected", 0, r.countProperties());
}
// But when adding an additional predicate on a property (e.g. agent):
final Predicate p2 = p1.and(p.agent.eq("agent-id"));
{
final RichAResult r = enrich(q.select(q.snapshot()).where(p2).run());
assertEquals("Only one record should be found now", 1, r.getSize());
assertEquals("One snapshots should be found", 1, r.countSnapshots());
assertEquals("No properties should be found since they haven't been selected", 0, r.countProperties());
}
}
@Test
@Parameters
public void testSelectPropertiesWithPropertyPredicate_CERV_698(Target allProperties) {
final String[] mp = createAndAddMediaPackagesSimple(2, 1, 1);
am.setProperty(p.agent.mk(mp[0], "agent-id"));
am.setProperty(p.approved.mk(mp[0], true));
am.setProperty(p.count.mk(mp[0], 1L));
am.setProperty(p.start.mk(mp[0], new Date(0)));
{
logger.info("No predicate");
final RichAResult r = enrich(q.select(allProperties).run());
assertEquals("Two records should match", 2, r.getSize());
assertEquals("No snapshots should be contained in the records", 0, r.countSnapshots());
assertEquals("Four properties should be contained in the records", 4, r.countProperties());
assertEquals("All four properties should belong to one media package",
4, sizeOf(r.getProperties().filter(Properties.byMediaPackageId(mp[0]))));
}
{
logger.info("'approved' == true");
final RichAResult r = enrich(q.select(allProperties).where(p.approved.eq(true)).run());
assertEquals("Only one record should match", 1, r.getSize());
assertEquals("Four properties should be contained", 4, r.countProperties());
}
if (true) return;
{
logger.info("'approved' == true or 'agent' == 'agent-id'");
final RichAResult r = enrich(q.select(allProperties).where(p.approved.eq(true).or(p.agent.eq("agent-id"))).run());
assertEquals("Only one record should match", 1, r.getSize());
assertEquals("Four properties should be contained", 4, r.countProperties());
}
{
logger.info("'approved' exists");
final RichAResult r = enrich(q.select(allProperties).where(p.approved.exists()).run());
assertEquals("Only one record should match", 1, r.getSize());
assertEquals("Four properties should be contained", 4, r.countProperties());
assertEquals("The matching record should represent the first media package",
mp[0], r.getRecords().map(ARecords.getMediaPackageId).head().get());
}
{
logger.info("'approved' notExists");
final RichAResult r = enrich(q.select(allProperties).where(p.approved.notExists()).run());
assertEquals("Only one record should match", 1, r.getSize());
assertEquals("The found record should represent the second media package since it does not have an 'approved' property",
mp[1], r.getRecords().map(ARecords.getMediaPackageId).head().get());
}
}
// parameter provider for above test
private Object parametersForTestSelectPropertiesWithPropertyPredicate_CERV_698() throws Exception {
setUp();
return $a(q.properties(), q.propertiesOf(), p.allProperties());
}
@Test
public void testSelectAllPropertiesOfNamespace() throws Exception {
final MediaPackage mp = mkMediaPackage(mkCatalog());
am.takeSnapshot(OWNER, mp);
am.setProperty(Property.mk(PropertyId.mk(mp.getIdentifier().toString(), "namespace-1", "prop-1"), Value.mk(true)));
am.setProperty(Property.mk(PropertyId.mk(mp.getIdentifier().toString(), "namespace-2", "prop-2"), Value.mk("value-2")));
{
final RichAResult r = enrich(q.select(q.propertiesOf("namespace-1")).run());
assertEquals("One record should be returned", 1, r.getSize());
assertEquals("No snapshots should be returned", 0, r.countSnapshots());
assertEquals("One property should be returned", 1, r.countProperties());
assertEquals("Property of namespace-1 should be returned",
PropertyId.mk(mp.getIdentifier().toString(), "namespace-1", "prop-1"),
r.getProperties().head2().getId());
}
{
final RichAResult r = enrich(q.select(q.propertiesOf("namespace-1")).where(q.hasPropertiesOf("namespace-2")).run());
assertEquals("One record should be returned", 1, r.getSize());
assertEquals("No snapshots should be returned", 0, r.countSnapshots());
assertEquals("One property should be returned", 1, r.countProperties());
assertEquals("Property of namespace-1 should be returned",
PropertyId.mk(mp.getIdentifier().toString(), "namespace-1", "prop-1"),
r.getProperties().head2().getId());
}
}
@Test
public void testSelectSnapshotAndProperties() throws Exception {
final MediaPackage mp1 = mkMediaPackage(mkCatalog());
am.takeSnapshot(OWNER, mp1);
// only select snapshots
{
final AResult r = q.select(q.snapshot()).run();
assertEquals("One record should be found", 1, r.getSize());
assertEquals("One snapshot should be found", 1, r.getRecords().bind(getSnapshot).toList().size());
assertEquals("No properties should be found", 0, r.getRecords().bind(getProperties).toList().size());
}
// select snapshots and properties
{
final AResult r = q.select(q.snapshot(), p.allProperties()).run();
assertEquals("One record should be found", 1, r.getSize());
assertEquals("One snapshot should be found", 1, r.getRecords().bind(getSnapshot).toList().size());
assertEquals("No properties should be found", 0, r.getRecords().bind(getProperties).toList().size());
}
}
@Test
public void testSelectByArchivedDate() throws Exception {
final Date backThen = DateTime.now().minusSeconds(5).withMillisOfSecond(0).toDate();
final MediaPackage mp1 = mkMediaPackage(mkCatalog());
am.takeSnapshot(OWNER, mp1);
final MediaPackage mp2 = mkMediaPackage(mkCatalog());
am.takeSnapshot(OWNER, mp2);
final Date now = DateTime.now().plusSeconds(1).withMillisOfSecond(0).toDate();
assertEquals("Two records should be found", 2, q.select(q.snapshot()).where(q.archived().le(now)).run().getSize());
assertEquals("No record should be found", 0, q.select(q.snapshot()).where(q.archived().gt(now)).run().getSize());
assertEquals("Two records should be found", 2, q.select(q.snapshot()).where(q.archived().ge(backThen)).run().getSize());
assertEquals("No record should be found", 0, q.select(q.snapshot()).where(q.archived().lt(backThen)).run().getSize());
}
@Test
public void testSelectByVersion() throws Exception {
final MediaPackage mp1 = mkMediaPackage(mkCatalog());
logger.info("Create 4 versions");
am.takeSnapshot(OWNER, mp1);
am.takeSnapshot(OWNER, mp1);
am.takeSnapshot(OWNER, mp1);
am.takeSnapshot(OWNER, mp1);
assertEquals("4 records should be found", 4, q.select(q.snapshot()).run().getSize());
assertEquals("4 records should be found", 4, q.select().run().getSize());
final Version latest;
{
AResult r = q.select(q.snapshot()).where(q.version().isLatest()).run();
assertEquals("1 latest record should be found", 1, r.getSize());
latest = r.getRecords().head2().getSnapshot().get().getVersion();
}
final Version first;
{
AResult r = q.select(q.snapshot()).where(q.version().isFirst()).run();
assertEquals("1 first record should be found", 1, r.getSize());
first = r.getRecords().head2().getSnapshot().get().getVersion();
}
assertTrue("The first version should be older", first.isOlder(latest));
assertTrue("The last version should be younger", latest.isYounger(first));
assertFalse("The versions should not be equal", latest.equals(first));
//
assertEquals("Three older records should be found", 3, q.select(q.snapshot()).where(q.version().lt(latest)).run().getSize());
assertEquals("4 records should be found", 4, q.select(q.snapshot()).where(q.version().le(latest)).run().getSize());
assertEquals("Three younger records should be found", 3, q.select(q.snapshot()).where(q.version().gt(first)).run().getSize());
assertEquals("4 records should be found", 4, q.select(q.snapshot()).where(q.version().ge(first)).run().getSize());
assertEquals("2 intermediate records should be found",
2, q.select(q.snapshot()).where(q.version().gt(first).and(q.version().lt(latest))).run().getSize());
//
logger.info("Now add another media package");
am.takeSnapshot(OWNER, mkMediaPackage(mkCatalog()));
assertEquals("Three older records should be found",
3, q.select(q.snapshot()).where(q.version().lt(latest).and(q.mediaPackageId(mp1.getIdentifier().toString()))).run().getSize());
assertEquals("Two latest versions should be found",
2, q.select(q.snapshot()).where(q.version().isLatest()).run().getSize());
assertEquals("Two first versions should be found",
2, q.select(q.snapshot()).where(q.version().isFirst()).run().getSize());
}
private Pred<Snapshot> findSnapshot(final String mpId, final Version version) {
return new Pred<Snapshot>() {
@Override public Boolean apply(Snapshot snapshot) {
return snapshot.getMediaPackage().getIdentifier().toString().equals(mpId) && snapshot.getVersion().equals(version);
}
};
}
/**
* CERV-1047
*/
@Test
public void testSelectBySnapshotFieldEqualsProperty() throws Exception {
final Snapshot[] mp1 = createAndAddMediaPackages(3, 2, 2, Opt.some("series-1"));
// fill asset manager a bit
final Snapshot[] mp2 = createAndAddMediaPackages(3, 1, 1, Opt.some("series-2"));
final Snapshot[] mp3 = createAndAddMediaPackages(3, 1, 1, Opt.<String>none());
am.setProperty(Properties.mkProperty(p.seriesId, mp1[0], "series-1"));
{
final RichAResult r = enrich(q.select(q.snapshot()).where(q.seriesId().eq(p.seriesId)).run());
assertEquals("Query should return all versions which are two", 2, r.getSize());
assertEquals(mp1[0].getMediaPackage().getIdentifier().toString(),
r.getSnapshots().head2().getMediaPackage().getIdentifier().toString());
}
{
final RichAResult r = enrich(q.select(q.snapshot()).where(q.seriesId().eq(p.seriesId).and(q.version().isLatest())).run());
assertEquals("Query should return only the latest version", 1, r.getSize());
assertEquals(mp1[0].getMediaPackage().getIdentifier().toString(),
r.getSnapshots().head2().getMediaPackage().getIdentifier().toString());
}
// now set a seriesId property to a media package that belongs to "series-2"
am.setProperty(Properties.mkProperty(p.seriesId, mp2[0], "series-1"));
{
final RichAResult r = enrich(q.select(q.snapshot()).where(q.seriesId().eq(p.seriesId).and(q.version().isLatest())).run());
assertEquals("Query should not return the media package of series-2", 1, r.getSize());
assertEquals(mp1[0].getMediaPackage().getIdentifier().toString(),
r.getSnapshots().head2().getMediaPackage().getIdentifier().toString());
}
{
// do a greater than comparison
final RichAResult r = enrich(q.select(q.snapshot()).where(q.seriesId().gt(p.seriesId).and(q.version().isLatest())).run());
assertEquals("Query should return the media package of series-2", 1, r.getSize());
assertEquals(mp2[0].getMediaPackage().getIdentifier().toString(),
r.getSnapshots().head2().getMediaPackage().getIdentifier().toString());
}
}
/**
* CERV-1047
* Test for selecting snapshots by version which is stored in a property of the media package.
*/
@Test
public void testSelectBySnapshotVersionEqualsVersionProperty() throws Exception {
final Snapshot[] mp1 = createAndAddMediaPackages(3, 3, 3, Opt.<String>none());
am.setProperty(Properties.mkProperty(p.versionId, mp1[0], mp1[0].getVersion()));
{
final RichAResult r = enrich(q.select(q.snapshot()).where(q.version().eq(p.versionId)).run());
assertEquals("Query should return only the first version", 1, r.getSize());
assertEquals(mp1[0].getMediaPackage().getIdentifier().toString(),
r.getSnapshots().head2().getMediaPackage().getIdentifier().toString());
}
// set version to version of second snapshot
am.setProperty(Properties.mkProperty(p.versionId, mp1[0], mp1[1].getVersion()));
{
final RichAResult r = enrich(q.select(q.snapshot()).where(q.version().eq(p.versionId)).run());
assertEquals("Query should now return only the second version", 1, r.getSize());
assertEquals(mp1[1].getMediaPackage().getIdentifier().toString(),
r.getSnapshots().head2().getMediaPackage().getIdentifier().toString());
}
}
@Test
public void testSelect1() throws Exception {
logger.info("Testing a select that caused an issue.");
final MediaPackage mp = mkMediaPackage(mkCatalog());
am.takeSnapshot(OWNER, mp);
final String mpId = mp.getIdentifier().toString();
RichAResult r = enrich(q.select(p.count.target(), p.approved.target())
.where(q.organizationId(DefaultOrganization.DEFAULT_ORGANIZATION_ID)
.and(q.mediaPackageId(mpId).and(q.version().isLatest())))
.run());
assertEquals(1, r.getSize());
}
@Ignore
@Test
public void testManyMediaPackages() throws Exception {
final long tStart = System.nanoTime();
final int mpCount = 1000;
final Stream<P2<String, Integer>> inserts = Stream.cont(inc()).take(mpCount).map(new FnX<Integer, P2<String, Integer>>() {
@Override public P2<String, Integer> applyX(Integer ignore) throws Exception {
final MediaPackage mp = mkMediaPackage(mkCatalog());
final String mpId = mp.getIdentifier().toString();
final int versions = (int) (Math.random() * 10.0 + 1.0);
for (int i = 0; i < Math.random() * 10 + 1; i++) {
am.takeSnapshot(OWNER, mp);
}
// set the legacy ID property
am.setProperty(p.legacyId.mk(mpId, "legacyId=" + mpId));
return Products.E.p2(mp.getIdentifier().toString(), versions);
}
}).eval();
final long tInserted = System.nanoTime();
{
RichAResult r = enrich(q.select(q.snapshot()).where(q.version().isLatest()).run());
assertEquals(mpCount, r.getSize());
assertEquals(mpCount, r.countSnapshots());
}
for (final P2<String, Integer> insert : inserts) {
final RichAResult r = enrich(q.select(p.legacyId.target()).where(q.mediaPackageId(insert.get1()).and(q.version().isLatest())).run());
assertEquals(1, r.getSize());
assertEquals(0, r.countSnapshots());
assertEquals(1, r.countProperties());
assertEquals("legacyId=" + r.getRecords().head().get().getMediaPackageId(), r.getProperties().head().get().getValue().get(Value.STRING));
}
final long tQueried = System.nanoTime();
logger.info("Insertion ms " + ((tInserted - tStart) / 1000000));
logger.info("Queries ms " + ((tQueried - tInserted) / 1000000));
}
@Test
public void testPredicateZero() throws Exception {
final MediaPackage mp1 = mkMediaPackage(mkCatalog());
am.takeSnapshot(OWNER, mp1);
{
final AResult r = q.select(q.snapshot()).run();
assertEquals("One record should be found", 1, r.getSize());
assertEquals("One snapshot should be found", 1, r.getRecords().bind(getSnapshot).toList().size());
assertEquals("No properties should be found", 0, r.getRecords().bind(getProperties).toList().size());
}
{
final AResult r = q.select(q.snapshot()).where(q.always()).run();
assertEquals("One record should be found", 1, r.getSize());
assertEquals("One snapshot should be found", 1, r.getRecords().bind(getSnapshot).toList().size());
assertEquals("No properties should be found", 0, r.getRecords().bind(getProperties).toList().size());
}
{
final AResult r = q.select(q.snapshot()).where(q.always().not()).run();
assertEquals("No record should be found", 0, r.getSize());
}
{
logger.info("Show an example use case of predicate's zero element");
final boolean selectAll = true;
final AResult r = q.select(q.snapshot()).where(selectAll ? q.always() : q.mediaPackageId("bla")).run();
assertEquals("One record should be found", 1, r.getSize());
assertEquals("One snapshot should be found", 1, r.getRecords().bind(getSnapshot).toList().size());
assertEquals("No properties should be found", 0, r.getRecords().bind(getProperties).toList().size());
}
}
@Test
public void testSelectByEndAndStartProperty() throws Exception {
final MediaPackage mp = mkMediaPackage(mkCatalog());
final String mpId = mp.getIdentifier().toString();
am.takeSnapshot(OWNER, mp);
final Date d0 = new Date(0);
final Date d1 = new Date(1);
final Date d3 = new Date(3);
assertTrue("The property should be set", am.setProperty(p.start.mk(mpId, d1)));
assertTrue("The property should be set", am.setProperty(p.end.mk(mpId, d3)));
logger.info("Select all media package's end from d0 and start to d3");
{
AResult r = q.select(q.snapshot()).where(q.mediaPackageId(mpId).and(p.start.le(d3)).and(p.end.ge(d0))).run();
assertEquals("One record should be found", 1, r.getSize());
}
}
@Test
public void testSelectByMultipleProperties() throws Exception {
final String[] mp = createAndAddMediaPackagesSimple(5, 1, 1);
final Version v3 = am.toVersion("3").get();
am.setProperty(p.agent.mk(mp[0], "agent"));
am.setProperty(p.versionId.mk(mp[0], v3));
am.setProperty(p.approved.mk(mp[0], true));
assertThat(
q.select(p.agent.target(), p.approved.target()).where(p.approved.eq(true).and(p.versionId.eq(v3)))
.run().getRecords().head().get().getProperties().map(Properties.getValue),
Matchers.containsInAnyOrder(equalTo((Value) Value.mk("agent")), equalTo((Value) Value.mk(true))));
}
@Test
public void testComparisons() throws Exception {
final MediaPackage mp = mkMediaPackage(mkCatalog());
final String mpId = mp.getIdentifier().toString();
am.takeSnapshot(OWNER, mp);
// set the milliseconds to 0 since MySQL (or the driver) rounds milliseconds to the next or previous
// second which may cause subsequent tests (.le(now)) to fail.
final Date now = DateTime.now().withMillisOfSecond(0).toDate();
logger.info("now=" + now);
// set up a property for each property type
am.setProperty(p.start.mk(mpId, now));
am.setProperty(p.agent.mk(mpId, "agent"));
am.setProperty(p.approved.mk(mpId, true));
am.setProperty(p.count.mk(mpId, 10L));
{
assertEquals(1, q.select(q.snapshot()).where(p.count.le(10L)).run().getSize());
assertEquals(1, q.select(q.snapshot()).where(p.count.ge(10L)).run().getSize());
assertEquals(1, q.select(q.snapshot()).where(p.count.eq(10L)).run().getSize());
assertEquals(0, q.select(q.snapshot()).where(p.count.lt(10L)).run().getSize());
assertEquals(0, q.select(q.snapshot()).where(p.count.gt(10L)).run().getSize());
assertEquals(1, q.select(q.snapshot()).where(p.count.lt(11L)).run().getSize());
assertEquals(1, q.select(q.snapshot()).where(p.count.gt(9L)).run().getSize());
}
{
assertEquals(1, q.select(q.snapshot()).where(p.start.le(now)).run().getSize());
assertEquals(1, q.select(q.snapshot()).where(p.start.ge(now)).run().getSize());
assertEquals(1, q.select(q.snapshot()).where(p.start.eq(now)).run().getSize());
assertEquals(0, q.select(q.snapshot()).where(p.start.lt(now)).run().getSize());
assertEquals(0, q.select(q.snapshot()).where(p.start.gt(now)).run().getSize());
assertEquals(1, q.select(q.snapshot()).where(p.start.lt(new Date(now.getTime() + 120000L))).run().getSize());
assertEquals(1, q.select(q.snapshot()).where(p.start.gt(new Date(now.getTime() - 120000L))).run().getSize());
}
}
@Test
public void testSelectBySeries() throws Exception {
final MediaPackage mp = mkMediaPackage();
logger.info("The series ID field of the media package links it to a series. Attached DublinCore catalogs are not relevant.");
mp.setSeries("series-1");
am.takeSnapshot(OWNER, mp);
assertEquals(1, q.select(q.snapshot()).where(q.seriesId().eq("series-1")).run().getSize());
assertEquals(0, q.select(q.snapshot()).where(q.seriesId().eq("series-2")).run().getSize());
}
@Test
public void testSelectWithoutTarget() throws Exception {
final String[] mp = createAndAddMediaPackagesSimple(5, 1, 1);
am.setProperty(p.agent.mk(mp[0], "agent-1"));
am.setProperty(p.agent.mk(mp[1], "agent-2"));
am.setProperty(p.count.mk(mp[2], 4L));
assertEquals("Five records should be found", 5, q.select().run().getSize());
for (final ARecord r : q.select().run()) {
assertTrue("No snapshots should be included in the record", r.getSnapshot().isNone());
assertTrue("No properties should be included in the record", r.getProperties().isEmpty());
}
}
@Test
public void testOrderBySnapshotField() throws Exception {
final String[] mp1 = createAndAddMediaPackagesSimple(1, 1, 1, Opt.some("series-1"));
final String[] mp2 = createAndAddMediaPackagesSimple(1, 1, 1, Opt.some("series-2"));
final String[] mp3 = createAndAddMediaPackagesSimple(1, 1, 1, Opt.some("series-3"));
{
final List<String> orgAsc = enrich(q.select(q.snapshot()).orderBy(q.seriesId().asc()).run())
.getSnapshots().bind(Snapshots.getSeriesId).toList();
final List<String> orgDesc = enrich(q.select(q.snapshot()).orderBy(q.seriesId().desc()).run())
.getSnapshots().bind(Snapshots.getSeriesId).toList();
assertEquals($("series-1", "series-2", "series-3").toList(), orgAsc);
assertEquals($("series-3", "series-2", "series-1").toList(), orgDesc);
}
{
assertEquals(
enrich(q.select(q.snapshot()).orderBy(q.archived().asc()).run())
.getSnapshots().map(Snapshots.getArchivalDate).toList(),
enrich(q.select(q.snapshot()).orderBy(q.archived().desc()).run())
.getSnapshots().map(Snapshots.getArchivalDate).reverse().toList());
}
{
assertEquals(
enrich(q.select(q.snapshot()).orderBy(q.version().asc()).run())
.getSnapshots().map(Snapshots.getVersion).toList(),
enrich(q.select(q.snapshot()).orderBy(q.version().desc()).run())
.getSnapshots().map(Snapshots.getVersion).reverse().toList());
}
}
@Test
public void testPaging() throws Exception {
final String[] mp1 = createAndAddMediaPackagesSimple(5, 1, 1, Opt.some("series-1"));
assertEquals(1, q.select().page(0, 1).where(q.seriesId().eq("series-1")).run().getSize());
assertEquals(3, q.select().page(0, 3).where(q.seriesId().eq("series-1")).run().getSize());
assertEquals(3, q.select().where(q.seriesId().eq("series-1")).page(0, 3).run().getSize());
assertEquals(1, q.select().page(4, 5).where(q.seriesId().eq("series-1")).run().getSize());
assertEquals(1, q.select().where(q.seriesId().eq("series-1")).page(4, 5).run().getSize());
}
}