blob: 9d6baa58740882e70615c1b83e122cfcfdff3259 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. 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. For additional information regarding
* copyright in this work, please see the NOTICE file in the top level
* directory of this distribution.
*/
package org.apache.usergrid.persistence.index.impl;
import java.io.IOException;
import java.util.HashMap;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.usergrid.persistence.collection.util.EntityUtils;
import org.apache.usergrid.persistence.core.scope.ApplicationScope;
import org.apache.usergrid.persistence.core.scope.ApplicationScopeImpl;
import org.apache.usergrid.persistence.core.test.UseModules;
import org.apache.usergrid.persistence.index.EntityIndex;
import org.apache.usergrid.persistence.index.EntityIndexBatch;
import org.apache.usergrid.persistence.index.EntityIndexFactory;
import org.apache.usergrid.persistence.index.IndexScope;
import org.apache.usergrid.persistence.index.SearchTypes;
import org.apache.usergrid.persistence.index.exceptions.QueryParseException;
import org.apache.usergrid.persistence.index.guice.TestIndexModule;
import org.apache.usergrid.persistence.index.query.CandidateResult;
import org.apache.usergrid.persistence.index.query.CandidateResults;
import org.apache.usergrid.persistence.index.query.Query;
import org.apache.usergrid.persistence.model.entity.Entity;
import org.apache.usergrid.persistence.model.entity.Id;
import org.apache.usergrid.persistence.model.entity.SimpleId;
import org.apache.usergrid.persistence.model.util.UUIDGenerator;
import com.google.inject.Inject;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
@RunWith( EsRunner.class )
@UseModules( { TestIndexModule.class } )
public class EntityConnectionIndexImplTest extends BaseIT {
private static final Logger log = LoggerFactory.getLogger( EntityConnectionIndexImplTest.class );
// @ClassRule
// public static ElasticSearchResource es = new ElasticSearchResource();
@Inject
public EntityIndexFactory ecif;
@Test
public void testBasicOperation() throws IOException, InterruptedException {
Id appId = new SimpleId( "application" );
ApplicationScope applicationScope = new ApplicationScopeImpl( appId );
// create a muffin
Entity muffin = new Entity( new SimpleId( UUIDGenerator.newTimeUUID(), "muffin" ) );
muffin = EntityIndexMapUtils.fromMap( muffin, new HashMap<String, Object>() {{
put( "size", "Large" );
put( "flavor", "Blueberry" );
put( "stars", 5 );
}} );
EntityUtils.setVersion( muffin, UUIDGenerator.newTimeUUID() );
Entity egg = new Entity( new SimpleId( UUIDGenerator.newTimeUUID(), "egg" ) );
egg = EntityIndexMapUtils.fromMap( egg, new HashMap<String, Object>() {{
put( "size", "Large" );
put( "type", "scramble" );
put( "stars", 5 );
}} );
EntityUtils.setVersion( egg, UUIDGenerator.newTimeUUID() );
Entity oj = new Entity( new SimpleId( UUIDGenerator.newTimeUUID(), "juice" ) );
oj = EntityIndexMapUtils.fromMap( oj, new HashMap<String, Object>() {{
put( "size", "Large" );
put( "type", "pulpy" );
put( "stars", 3 );
}} );
EntityUtils.setVersion( oj, UUIDGenerator.newTimeUUID() );
// create a person who likes muffins
Id personId = new SimpleId( UUIDGenerator.newTimeUUID(), "person" );
assertNotNull( personId );
assertNotNull( personId.getType() );
assertNotNull( personId.getUuid() );
// index connection of "person Dave likes Large Blueberry muffin"
IndexScope searchScope = new IndexScopeImpl( personId, "likes" );
//create another scope we index in, want to be sure these scopes are filtered
IndexScope otherIndexScope =
new IndexScopeImpl( new SimpleId( UUIDGenerator.newTimeUUID(), "animal" ), "likes" );
EntityIndex personLikesIndex = ecif.createEntityIndex( applicationScope );
EntityIndexBatch batch = personLikesIndex.createBatch();
//add to both scopes
//add a muffin
batch.index( searchScope, muffin );
batch.index( otherIndexScope, muffin );
//add the eggs
batch.index( searchScope, egg );
batch.index( otherIndexScope, egg );
//add the oj
batch.index( searchScope, oj );
batch.index( otherIndexScope, oj );
batch.executeAndRefresh();
personLikesIndex.refresh();
EsTestUtils.waitForTasks(personLikesIndex);
Thread.sleep( 1000 );
// now, let's search for muffins
CandidateResults likes = personLikesIndex
.search( searchScope, SearchTypes.fromTypes( muffin.getId().getType() ), Query.fromQL( "select *" ) );
assertEquals( 1, likes.size() );
assertEquals( muffin.getId(), likes.get( 0 ).getId() );
// now, let's search for egg
likes = personLikesIndex
.search( searchScope, SearchTypes.fromTypes( egg.getId().getType() ), Query.fromQL( "select *" ) );
assertEquals( 1, likes.size() );
assertEquals( egg.getId(), likes.get( 0 ).getId() );
// search for OJ
likes = personLikesIndex
.search( searchScope, SearchTypes.fromTypes( oj.getId().getType() ), Query.fromQL( "select *" ) );
assertEquals( 1, likes.size() );
assertEquals( oj.getId(), likes.get( 0 ).getId() );
//now lets search for all explicitly
likes = personLikesIndex.search( searchScope,
SearchTypes.fromTypes( muffin.getId().getType(), egg.getId().getType(), oj.getId().getType() ),
Query.fromQL( "select *" ) );
assertEquals( 3, likes.size() );
assertContains( egg.getId(), likes );
assertContains( muffin.getId(), likes );
assertContains( oj.getId(), likes );
//now lets search for all explicitly
likes = personLikesIndex.search( searchScope, SearchTypes.allTypes(), Query.fromQL( "select *" ) );
assertEquals( 3, likes.size() );
assertContains( egg.getId(), likes );
assertContains( muffin.getId(), likes );
assertContains( oj.getId(), likes );
//now search all entity types with a query that returns a subset
likes = personLikesIndex.search( searchScope,
SearchTypes.fromTypes( muffin.getId().getType(), egg.getId().getType(), oj.getId().getType() ),
Query.fromQL( "select * where stars = 5" ) );
assertEquals( 2, likes.size() );
assertContains( egg.getId(), likes );
assertContains( muffin.getId(), likes );
//now search with no types, we should get only the results that match
likes = personLikesIndex
.search( searchScope, SearchTypes.allTypes(), Query.fromQL( "select * where stars = 5" ) );
assertEquals( 2, likes.size() );
assertContains( egg.getId(), likes );
assertContains( muffin.getId(), likes );
}
@Test
public void testDelete() throws IOException, InterruptedException {
Id appId = new SimpleId( "application" );
ApplicationScope applicationScope = new ApplicationScopeImpl( appId );
// create a muffin
Entity muffin = new Entity( new SimpleId( UUIDGenerator.newTimeUUID(), "muffin" ) );
muffin = EntityIndexMapUtils.fromMap( muffin, new HashMap<String, Object>() {{
put( "size", "Large" );
put( "flavor", "Blueberry" );
put( "stars", 5 );
}} );
EntityUtils.setVersion( muffin, UUIDGenerator.newTimeUUID() );
Entity egg = new Entity( new SimpleId( UUIDGenerator.newTimeUUID(), "egg" ) );
egg = EntityIndexMapUtils.fromMap( egg, new HashMap<String, Object>() {{
put( "size", "Large" );
put( "type", "scramble" );
put( "stars", 5 );
}} );
EntityUtils.setVersion( egg, UUIDGenerator.newTimeUUID() );
Entity oj = new Entity( new SimpleId( UUIDGenerator.newTimeUUID(), "juice" ) );
oj = EntityIndexMapUtils.fromMap( oj, new HashMap<String, Object>() {{
put( "size", "Large" );
put( "type", "pulpy" );
put( "stars", 3 );
}} );
EntityUtils.setVersion( oj, UUIDGenerator.newTimeUUID() );
// create a person who likes muffins
Id personId = new SimpleId( UUIDGenerator.newTimeUUID(), "person" );
assertNotNull( personId );
assertNotNull( personId.getType() );
assertNotNull( personId.getUuid() );
// index connection of "person Dave likes Large Blueberry muffin"
IndexScope searchScope = new IndexScopeImpl( personId, "likes" );
//create another scope we index in, want to be sure these scopes are filtered
IndexScope otherIndexScope =
new IndexScopeImpl( new SimpleId( UUIDGenerator.newTimeUUID(), "animal" ), "likes" );
EntityIndex personLikesIndex = ecif.createEntityIndex( applicationScope );
EntityIndexBatch batch = personLikesIndex.createBatch();
//add to both scopes
//add a muffin
batch.index( searchScope, muffin );
batch.index( otherIndexScope, muffin );
//add the eggs
batch.index( searchScope, egg );
batch.index( otherIndexScope, egg );
//add the oj
batch.index( searchScope, oj );
batch.index( otherIndexScope, oj );
batch.executeAndRefresh();
personLikesIndex.refresh();
EsTestUtils.waitForTasks( personLikesIndex );
Thread.sleep( 1000 );
// now, let's search for muffins
CandidateResults likes = personLikesIndex.search( searchScope,
SearchTypes.fromTypes( muffin.getId().getType(), egg.getId().getType(), oj.getId().getType() ),
Query.fromQL( "select *" ) );
assertEquals( 3, likes.size() );
assertContains( egg.getId(), likes );
assertContains( muffin.getId(), likes );
assertContains( oj.getId(), likes );
//now delete them
batch.deindex( searchScope, egg );
batch.deindex( searchScope, muffin );
batch.deindex( searchScope, oj );
batch.executeAndRefresh();
likes = personLikesIndex.search( searchScope,
SearchTypes.fromTypes( muffin.getId().getType(), egg.getId().getType(), oj.getId().getType() ),
Query.fromQL( "select *" ) );
assertEquals( 0, likes.size() );
}
private void assertContains( final Id id, final CandidateResults results ) {
for ( CandidateResult result : results ) {
if ( result.getId().equals( id ) ) {
return;
}
}
fail( String.format( "Could not find id %s in candidate results", id ) );
}
}