package org.atlasapi.persistence;
import java.util.Map;
import com.metabroadcast.applications.client.model.internal.Application;
import org.atlasapi.application.v3.DefaultApplication;
import org.atlasapi.media.channel.Channel;
import org.atlasapi.media.channel.ChannelGroup;
import org.atlasapi.media.channel.ChannelGroupStore;
import org.atlasapi.media.channel.Platform;
import org.atlasapi.media.channel.ServiceChannelStore;
import org.atlasapi.media.entity.ChildRef;
import org.atlasapi.media.entity.ContentGroup;
import org.atlasapi.media.entity.EntityType;
import org.atlasapi.media.entity.Event;
import org.atlasapi.media.entity.Identified;
import org.atlasapi.media.entity.Item;
import org.atlasapi.media.entity.MediaType;
import org.atlasapi.media.entity.Organisation;
import org.atlasapi.media.entity.Person;
import org.atlasapi.media.entity.Publisher;
import org.atlasapi.media.entity.Schedule;
import org.atlasapi.media.entity.Topic;
import org.atlasapi.media.product.Product;
import org.atlasapi.media.product.ProductStore;
import org.atlasapi.media.segment.Segment;
import org.atlasapi.media.segment.SegmentRef;
import org.atlasapi.media.segment.SegmentResolver;
import org.atlasapi.media.segment.SegmentWriter;
import org.atlasapi.messaging.v3.MessagingModule;
import org.atlasapi.persistence.content.ContentGroupResolver;
import org.atlasapi.persistence.content.ContentGroupWriter;
import org.atlasapi.persistence.content.ContentResolver;
import org.atlasapi.persistence.content.ContentWriter;
import org.atlasapi.persistence.content.KnownTypeContentResolver;
import org.atlasapi.persistence.content.organisation.OrganisationStore;
import org.atlasapi.persistence.content.people.PersonStore;
import org.atlasapi.persistence.content.schedule.mongo.MongoScheduleStore;
import org.atlasapi.persistence.event.EventResolver;
import org.atlasapi.persistence.event.EventWriter;
import org.atlasapi.persistence.logging.MongoLoggingAdapter;
import org.atlasapi.persistence.lookup.entry.LookupEntry;
import org.atlasapi.persistence.lookup.entry.LookupEntryStore;
import org.atlasapi.persistence.topic.TopicStore;
import com.metabroadcast.common.base.Maybe;
import com.metabroadcast.common.persistence.MongoTestHelper;
import com.metabroadcast.common.persistence.mongo.DatabasedMongo;
import com.metabroadcast.common.properties.Parameter;
import com.metabroadcast.common.queue.Message;
import com.metabroadcast.common.queue.MessageConsumerFactory;
import com.metabroadcast.common.queue.MessageSender;
import com.metabroadcast.common.queue.MessageSenderFactory;
import com.metabroadcast.common.queue.MessageSerializer;
import com.metabroadcast.common.queue.MessagingException;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.mongodb.Mongo;
import com.mongodb.ReadPreference;
import org.joda.time.DateTime;
import org.junit.Before;
import org.junit.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;
import static org.mockito.Mockito.mock;
public class ConstructorBasedMongoContentPersistenceModuleIT {
private final Mongo mongo = MongoTestHelper.anEmptyMongo();
private final DatabasedMongo db = new DatabasedMongo(mongo, "atlas");
private final MongoLoggingAdapter adapterLog = new MongoLoggingAdapter(db);
private final MessagingModule messagingModule = new MessagingModule(){
@Override
public MessageSenderFactory messageSenderFactory() {
return new MessageSenderFactory() {
@Override
public <M extends Message> MessageSender<M> makeMessageSender(String destination,
MessageSerializer<? super M> serializer) {
return new MessageSender<M>() {
@Override
public void close() throws Exception {
}
@Override
public void sendMessage(M message)
throws MessagingException {
}
@Override
public void sendMessage(M m, byte[] bytes)
throws MessagingException {
}
};
}
};
}
@Override
public MessageConsumerFactory<?> messageConsumerFactory() {
return null;
}
};
private ConstructorBasedMongoContentPersistenceModule module;
private ConstructorBasedMongoContentPersistenceModule moduleWithProcessingConfigTrue;
@Before
public void setUp() throws Exception {
module = new ConstructorBasedMongoContentPersistenceModule(
mongo,
db,
messagingModule,
"atlas-audit",
adapterLog,
ReadPreference.primary(),
"ContentChanges",
"TopicChanges",
"ScheduleChanges",
"ContentGroupChanges",
"EventChanges",
"OrganisationChanges",
true,
true,
Parameter.valueOf("false"),
"EquivAssert"
);
moduleWithProcessingConfigTrue = new ConstructorBasedMongoContentPersistenceModule(
mongo,
db,
messagingModule,
"atlas-audit",
adapterLog,
ReadPreference.primary(),
"ContentChanges",
"TopicChanges",
"ScheduleChanges",
"ContentGroupChanges",
"EventChanges",
"OrganisationChanges",
true,
true,
Parameter.valueOf("true"),
"EquivAssert"
);
}
@Test
public void testContentWritingAndRetrievalWithContentResolver() {
ContentWriter contentWriter = module.contentWriter();
ContentResolver contentResolver = module.contentResolver();
LookupEntryStore lookupStore = module.lookupStore();
String uri = "itemUri";
Item item = new Item(uri, "itemCurie", Publisher.BBC);
item.setTitle("I am a title");
contentWriter.createOrUpdate(item);
contentWriter.createOrUpdate(item);
Iterable<LookupEntry> entries = lookupStore.entriesForCanonicalUris(ImmutableSet.of(item.getCanonicalUri()));
LookupEntry entry = Iterables.getOnlyElement(entries);
Long id = entry.id();
assertThat(id, is(not(nullValue())));
assertThat(id, is(item.getId()));
Maybe<Identified> moreContent = contentResolver.findByCanonicalUris(ImmutableSet.of(uri)).get(uri);
assertThat((Item) moreContent.requireValue(), is(equalTo(item)));
assertThat(moreContent.requireValue().getId(), is(equalTo(id)));
assertThat(((Item) moreContent.requireValue()).getTitle(), is(equalTo(item.getTitle())));
String newTitle = "Changed title";
item.setTitle(newTitle);
item.setId(1234L);
contentWriter.createOrUpdate(item);
moreContent = contentResolver.findByCanonicalUris(ImmutableSet.of(uri)).get(uri);
assertThat((Item) moreContent.requireValue(), is(equalTo(item)));
//ID setting is currently disabled, so this check is not valid
//assertThat(((Item) moreContent.requireValue()).getStringId(), is(equalTo(id)));
assertThat(((Item) moreContent.requireValue()).getTitle(), is(equalTo(newTitle)));
}
@Test
public void testContentWritingAndRetrievalWithGivenId() {
ContentWriter contentWriter = module.nonIdSettingContentWriter();
ContentResolver contentResolver = module.contentResolver();
LookupEntryStore lookupStore = module.lookupStore();
String uri = "itemUri";
Item item = new Item(uri, "itemCurie", Publisher.BBC);
item.setTitle("I am a title");
item.setId(1L);
contentWriter.createOrUpdate(item);
Iterable<LookupEntry> entries = lookupStore.entriesForCanonicalUris(
ImmutableSet.of(item.getCanonicalUri())
);
Long lookupId = Iterables.getOnlyElement(entries).id();
assertThat(lookupId, is(not(nullValue())));
assertThat(lookupId, is(item.getId()));
Maybe<Identified> moreContent = contentResolver.findByCanonicalUris(
ImmutableSet.of(uri)
).get(uri);
assertThat(moreContent.requireValue().getId(), is(equalTo(lookupId)));
}
@Test
public void testContentWritingAndRetrievalKnownTypeContentResolver() {
ContentWriter contentWriter = module.contentWriter();
LookupEntryStore lookupStore = module.lookupStore();
KnownTypeContentResolver knownTypeContentResolver = module.knownTypeContentResolver();
String uri = "itemUri";
Item item = new Item(uri, "itemCurie", Publisher.BBC);
item.setTitle("I am a title");
contentWriter.createOrUpdate(item);
Iterable<LookupEntry> entries = lookupStore.entriesForCanonicalUris(ImmutableSet.of(item.getCanonicalUri()));
LookupEntry entry = Iterables.getOnlyElement(entries);
Long id = entry.id();
assertThat(id, is(not(nullValue())));
assertThat(id, is(item.getId()));
Maybe<Identified> maybeContent = knownTypeContentResolver.findByLookupRefs(ImmutableSet.of(entry.lookupRef())).get(uri);
assertThat((Item) maybeContent.requireValue(), is(equalTo(item)));
assertThat(maybeContent.requireValue().getId(), is(equalTo(id)));
assertThat(((Item) maybeContent.requireValue()).getTitle(), is(equalTo(item.getTitle())));
}
@Test
public void testContentGroupWritingAndRetrieval() {
ContentGroupWriter contentGroupWriter = module.contentGroupWriter();
ContentGroupResolver contentGroupResolver = module.contentGroupResolver();
String uri = "itemUri";
ContentGroup contentGroup = new ContentGroup(uri, Publisher.BBC);
contentGroupWriter.createOrUpdate(contentGroup);
Maybe<Identified> moreContentGroup = contentGroupResolver.findByCanonicalUris(ImmutableSet.of(uri)).get(uri);
assertThat((ContentGroup) moreContentGroup.requireValue(), is(equalTo(contentGroup)));
assertThat(((ContentGroup) moreContentGroup.requireValue()).getPublisher(), is(equalTo(Publisher.BBC)));
}
@Test
public void testEventWritingAndRetrieval() {
EventWriter eventWriter = module.eventWriter();
EventResolver eventResolver = module.eventResolver();
Topic topic = new Topic(100l, "namespace", "value");
topic.setCanonicalUri("uri");
topic.setCurie("curie");
topic.setPublisher(Publisher.METABROADCAST);
Iterable<Topic> eventGroups = ImmutableSet.of(topic);
Person person = new Person("uri", "itemCurie", Publisher.METABROADCAST);
Iterable<Person> members = ImmutableSet.of(person);
Organisation organisation = new Organisation(members, ImmutableSet.of("altTitle"));
Item item = new Item("uri", "itemCurie", Publisher.METABROADCAST);
item.setTitle("I am a title");
ChildRef childRef = new ChildRef(100l, "uri", "sortKey", DateTime.now(), EntityType.ITEM);
Event event = Event.builder()
.withTitle("title")
.withPublisher(Publisher.METABROADCAST)
.withVenue(topic)
.withStartTime(DateTime.now().minusHours(1))
.withEndTime(DateTime.now())
.withParticipants(ImmutableSet.of(person))
.withOrganisations(ImmutableSet.of(organisation))
.withEventGroups(eventGroups)
.withContent(ImmutableSet.of(childRef))
.build()
;
event.setCanonicalUri("uri");
eventWriter.createOrUpdate(event);
Optional<Event> moreEvent = eventResolver.fetch("uri");
assertThat(moreEvent.get(), is(equalTo(event)));
assertThat(moreEvent.get(), is(equalTo(event)));
}
@Test
public void testSegmentWritingAndRetrieval() {
SegmentWriter segmentWriter = module.segmentWriter();
SegmentResolver segmentResolver = module.segmentResolver();
Segment segment = new Segment();
segment.setPublisher(Publisher.BBC);
segment.setCanonicalUri("uri");
segment.setTitle("title");
segment.setCurie("itemCurie");
segmentWriter.write(segment);
SegmentRef segmentRef = new SegmentRef(103823l);
Map<SegmentRef, Maybe<Segment>> segmentMap = segmentResolver.resolveById(ImmutableList.of(segmentRef));
Maybe<Segment> maybeSegment = segmentMap.get(segmentRef);
assertThat(maybeSegment.requireValue(), is(equalTo(segment)));
}
@Test
public void testOrganisationWritingAndRetrieval() {
OrganisationStore organisationStore = module.organisationStore();
Person person = new Person("uri", "itemCurie", Publisher.METABROADCAST);
Iterable<Person> members = ImmutableSet.of(person);
Organisation organisation = new Organisation(members, ImmutableSet.of("altTitle"));
organisation.setCanonicalUri("uri");
organisation.setId(100l);
organisation.setPublisher(Publisher.METABROADCAST);
organisationStore.createOrUpdateOrganisation(organisation);
Optional<Organisation> organisationOptional = organisationStore.organisation("uri");
assertThat(organisationOptional.get(), is(equalTo(organisation)));
}
@Test
public void testPersonWritingAndRetrieval() {
PersonStore personStore = module.personStore();
Person person = new Person("uri", "itemCurie", Publisher.METABROADCAST);
personStore.createOrUpdatePerson(person);
Optional<Person> personOptional = personStore.person("uri");
assertThat(personOptional.get(), is(equalTo(person)));
}
@Test
public void testChannelWritingAndRetrievalWithProcessingConfigTrue() {
ServiceChannelStore serviceChannelStore = moduleWithProcessingConfigTrue.channelStore();
serviceChannelStore.start();
Channel channel = Channel.builder()
.withSource(Publisher.BBC)
.withTitle("title")
.withHighDefinition(false)
.withMediaType(MediaType.AUDIO)
.withUri("uri")
.build();
serviceChannelStore.createOrUpdate(channel);
Maybe<Channel> channelMaybe = serviceChannelStore.fromUri("uri");
serviceChannelStore.shutdown();
assertThat(channelMaybe.requireValue(), is(equalTo(channel)));
}
@Test
public void testChannelGroupWritingAndRetrieval() {
ChannelGroupStore channelGroupStore = module.channelGroupStore();
ChannelGroup channelGroup = new Platform();
channelGroup.setPublisher(Publisher.BBC);
channelGroup.setCanonicalUri("uri");
channelGroup.setCurie("itemCurie");
channelGroupStore.createOrUpdate(channelGroup);
Optional<ChannelGroup> channelGroupMaybe = channelGroupStore.channelGroupFor("uri");
assertThat(channelGroupMaybe.get(), is(equalTo(channelGroup)));
}
@Test
public void testProductWritingAndRetrieval() {
ProductStore productStore = module.productStore();
Product product = new Product();
product.setPublisher(Publisher.BBC);
product.setCurie("itemCurie");
product.setCanonicalUri("uri");
productStore.store(product);
Optional<Product> productOptional = productStore.productForSourceIdentified(
Publisher.BBC,
"uri"
);
assertThat(productOptional.get(), is(equalTo(product)));
}
@Test
public void testTopicWritingAndRetrieval() {
TopicStore topicStore = module.topicStore();
Topic topic = new Topic(103823l, "namespace", "value");
topic.setCanonicalUri("uri");
topic.setPublisher(Publisher.BBC);
topicStore.write(topic);
Maybe<Topic> topicMaybe = topicStore.topicFor("namespace", "value");
assertThat(topicMaybe.requireValue(), is(equalTo(topic)));
}
@Test
public void testScheduleWritingAndRetrieval() {
ServiceChannelStore channelStore = module.channelStore();
channelStore.start();
MongoScheduleStore scheduleStore = module.scheduleStore(channelStore);
String uri = "itemUri";
Item item = new Item(uri, "itemCurie", Publisher.BBC);
item.setTitle("I am a title");
Channel channel = Channel.builder()
.withSource(Publisher.BBC)
.withTitle("title")
.withHighDefinition(false)
.withMediaType(MediaType.AUDIO)
.withUri("uri")
.withKey("key")
.build();
item.setPresentationChannel(channel);
Application application = mock(Application.class);
scheduleStore.writeScheduleFor(ImmutableList.of(item));
Schedule schedule = scheduleStore.schedule(
DateTime.now().minusHours(12),
DateTime.now(),
ImmutableList.of(channel),
ImmutableList.of(Publisher.BBC),
Optional.of(application)
);
Schedule.ScheduleChannel scheduleChannel = Iterables.getOnlyElement(schedule.scheduleChannels());
channelStore.shutdown();
assertThat(scheduleChannel.channel(), is(equalTo(channel)));
}
}