/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache 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://www.apache.org/licenses/LICENSE-2.0
*
* 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.apache.usergrid.mongo;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import org.bson.types.ObjectId;
import org.junit.Ignore;
import org.junit.Test;
import org.apache.usergrid.mongo.protocol.OpDelete;
import org.apache.usergrid.persistence.Entity;
import org.apache.usergrid.persistence.EntityManager;
import org.apache.usergrid.persistence.index.query.Query;
import org.apache.usergrid.persistence.Results;
import org.apache.usergrid.persistence.SimpleEntityRef;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.MongoException;
import com.mongodb.WriteConcern;
import com.mongodb.WriteResult;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@Ignore
public class BasicMongoTest extends AbstractMongoTest {
@Test
public void insertTest() throws Exception {
DB db = getDb();
BasicDBObject doc = new BasicDBObject();
doc.put( "name", "nico" );
doc.put( "color", "tabby" );
WriteResult result = db.getCollection( "inserttests" ).insert( doc );
ObjectId savedOid = doc.getObjectId( "_id" );
assertNull( result.getError() );
// check we've created the collection
Set<String> colls = db.getCollectionNames();
assertTrue( colls.contains( "inserttests" ) );
// iterate the collection to ensure we can retrieve the object
DBCollection coll = db.getCollection( "inserttests" );
DBCursor cur = coll.find();
BasicDBObject returnedObject = null;
assertTrue( cur.hasNext() );
returnedObject = ( BasicDBObject ) cur.next();
assertFalse( cur.hasNext() );
UUID id = UUID.fromString( returnedObject.get( "uuid" ).toString() );
//this should work. Appears to be the type of ObjectId getting lost on column serialization
ObjectId returnedOid = new ObjectId( returnedObject.getString( "_id" ) );
assertEquals( "nico", returnedObject.get( "name" ) );
assertEquals( "tabby", returnedObject.get( "color" ) );
assertEquals( savedOid, returnedOid );
assertNotNull( id );
BasicDBObject query = new BasicDBObject();
query.put( "_id", savedOid );
// now load by the mongo Id. Users will use this the most to read data.
returnedObject = new BasicDBObject( db.getCollection( "inserttests" ).findOne( query ).toMap() );
assertEquals( "nico", returnedObject.get( "name" ) );
assertEquals( "tabby", returnedObject.get( "color" ) );
assertEquals( savedOid, new ObjectId( returnedObject.getString( "_id" ) ) );
assertEquals( id.toString(), returnedObject.get( "uuid" ) );
// check we can find it when using the native entity manager
UUID appId = emf.lookupApplication( "test-organization/test-app" );
EntityManager em = emf.getEntityManager( appId );
Entity entity = em.get( new SimpleEntityRef( (String)returnedObject.get("type"), id ));
assertNotNull( entity );
assertEquals( "nico", entity.getProperty( "name" ) );
assertEquals( "tabby", entity.getProperty( "color" ) );
}
@Test
public void insertDuplicateTest() throws Exception {
DB db = getDb();
BasicDBObject doc = new BasicDBObject();
doc.put( "username", "insertduplicate" );
WriteResult result = db.getCollection( "users" ).insert( doc );
assertNull( result.getError() );
// check we've created the collection
Set<String> colls = db.getCollectionNames();
assertTrue( colls.contains( "users" ) );
// iterate the collection to ensure we can retrieve the object
doc = new BasicDBObject();
doc.put( "username", "insertduplicate" );
String message = null;
try {
result = db.getCollection( "users" ).insert( doc );
}
catch ( MongoException me ) {
message = me.getMessage();
}
assertNotNull( message );
assertTrue( message.contains(
"Entity users requires that property named username be unique, value of insertduplicate exists" ) );
}
@Test
public void updateTest() throws Exception {
DB db = getDb();
BasicDBObject doc = new BasicDBObject();
doc.put( "name", "nico" );
doc.put( "color", "tabby" );
WriteResult result = db.getCollection( "updatetests" ).insert( doc );
ObjectId savedOid = doc.getObjectId( "_id" );
assertNull( result.getError() );
// check we've created the collection
Set<String> colls = db.getCollectionNames();
assertTrue( colls.contains( "updatetests" ) );
// iterate the collection to ensure we can retrieve the object
DBCollection coll = db.getCollection( "updatetests" );
DBCursor cur = coll.find();
BasicDBObject returnedObject = null;
assertTrue( cur.hasNext() );
returnedObject = ( BasicDBObject ) cur.next();
assertFalse( cur.hasNext() );
UUID id = UUID.fromString( returnedObject.get( "uuid" ).toString() );
//this should work. Appears to be the type of ObjectId getting lost on column serialization
ObjectId returnedOid = new ObjectId( returnedObject.getString( "_id" ) );
assertEquals( "nico", returnedObject.get( "name" ) );
assertEquals( "tabby", returnedObject.get( "color" ) );
assertEquals( savedOid, returnedOid );
assertNotNull( id );
BasicDBObject query = new BasicDBObject();
query.put( "_id", savedOid );
// now load by the mongo Id. Users will use this the most to read data.
returnedObject = new BasicDBObject( db.getCollection( "updatetests" ).findOne( query ).toMap() );
assertEquals( "nico", returnedObject.get( "name" ) );
assertEquals( "tabby", returnedObject.get( "color" ) );
assertEquals( savedOid, new ObjectId( returnedObject.getString( "_id" ) ) );
assertEquals( id.toString(), returnedObject.get( "uuid" ) );
//now update the object and save it
BasicDBObject object = new BasicDBObject();
object.put( "newprop", "newvalue" );
object.put( "color", "black" );
db.getCollection( "updatetests" ).update( query, object );
// check we can find it when using the native entity manager
Thread.sleep( 5000 );
UUID appId = emf.lookupApplication( "test-organization/test-app" );
EntityManager em = emf.getEntityManager( appId );
Entity entity = em.get( new SimpleEntityRef( (String)returnedObject.get("type"), id ) );
assertNotNull( entity );
assertEquals( "nico", entity.getProperty( "name" ) );
assertEquals( "black", entity.getProperty( "color" ) );
assertEquals( "newvalue", entity.getProperty( "newprop" ) );
//now check it in the client
returnedObject = new BasicDBObject( db.getCollection( "updatetests" ).findOne( query ).toMap() );
assertEquals( "nico", returnedObject.get( "name" ) );
assertEquals( "black", returnedObject.get( "color" ) );
assertEquals( "newvalue", returnedObject.get( "newprop" ) );
assertEquals( savedOid, new ObjectId( returnedObject.getString( "_id" ) ) );
assertEquals( id.toString(), returnedObject.get( "uuid" ) );
}
@Test
public void deleteTest() throws Exception {
DB db = getDb();
BasicDBObject doc = new BasicDBObject();
doc.put( "name", "nico" );
doc.put( "color", "tabby" );
WriteResult result = db.getCollection( "deletetests" ).insert( doc );
ObjectId savedOid = doc.getObjectId( "_id" );
assertNull( result.getError() );
BasicDBObject query = new BasicDBObject();
query.put( "_id", savedOid );
// now load by the mongo Id. Users will use this the most to read data.
BasicDBObject returnedObject = new BasicDBObject( db.getCollection( "deletetests" ).findOne( query ).toMap() );
assertEquals( "nico", returnedObject.get( "name" ) );
assertEquals( "tabby", returnedObject.get( "color" ) );
// TODO uncomment me assertEquals(savedOid,
// returnedObject.getObjectId("_id"));
UUID id = UUID.fromString( returnedObject.get( "uuid" ).toString() );
// now delete the object
db.getCollection( "deletetests" ).remove( returnedObject, WriteConcern.SAFE );
DBObject searched = db.getCollection( "deletetests" ).findOne( query );
assertNull( searched );
// check it has been deleted
UUID appId = emf.lookupApplication( "test-organization/test-app" );
EntityManager em = emf.getEntityManager( appId );
Entity entity = em.get( new SimpleEntityRef( (String)returnedObject.get("type"), id ) );
assertNull( entity );
}
@Test
@Ignore("Really slow on the delete, not a good unit tests atm")
public void deleteBatchTest() throws Exception {
DB db = getDb();
int count = ( int ) ( OpDelete.BATCH_SIZE * 1.5 );
List<DBObject> docs = new ArrayList<DBObject>( count );
for ( int i = 0; i < count; i++ ) {
BasicDBObject doc = new BasicDBObject();
doc.put( "index", i );
docs.add( doc );
}
WriteResult result = db.getCollection( "deletebatchtests" ).insert( docs );
assertNull( result.getLastError().getErrorMessage() );
//iterate over all the data to make sure it's been inserted
DBCursor cursor = db.getCollection( "deletebatchtests" ).find();
for ( int i = 0; i < count && cursor.hasNext(); i++ ) {
int index = new BasicDBObject( cursor.next().toMap() ).getInt( "index" );
assertEquals( i, index );
}
BasicDBObject query = new BasicDBObject();
query.put( "index", new BasicDBObject( "$lte", count ) );
// now delete the objects
db.getCollection( "deletebatchtests" ).remove( query, WriteConcern.SAFE );
//now try and iterate, there should be no results
cursor = db.getCollection( "deletebatchtests" ).find();
assertFalse( cursor.hasNext() );
// check it has been deleted
UUID appId = emf.lookupApplication( "test-organization/test-app" );
EntityManager em = emf.getEntityManager( appId );
Results results =
em.searchCollection( new SimpleEntityRef( "application", appId ), "deletebatchtests", new Query() );
assertEquals( 0, results.size() );
}
}