/**
* Copyright (c) 2002-2011 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.neo4j.index.impl.lucene;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.PropertyContainer;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.index.Index;
import org.neo4j.helpers.collection.MapUtil;
import org.neo4j.index.Neo4jTestCase;
import org.neo4j.kernel.EmbeddedGraphDatabase;
import org.neo4j.kernel.impl.index.IndexStore;
public class TestMigration
{
@Test
public void canReadAndUpgradeOldIndexStoreFormat() throws Exception
{
String path = "target/var/old-index-store";
Neo4jTestCase.deleteFileOrDirectory( new File( path ) );
GraphDatabaseService db = new EmbeddedGraphDatabase( path );
db.shutdown();
InputStream stream = getClass().getClassLoader().getResourceAsStream( "old-index.db" );
writeFile( stream, new File( path, "index.db" ) );
db = new EmbeddedGraphDatabase( path );
assertTrue( db.index().existsForNodes( "indexOne" ) );
Index<Node> indexOne = db.index().forNodes( "indexOne" );
verifyConfiguration( db, indexOne, LuceneIndexProvider.EXACT_CONFIG );
assertTrue( db.index().existsForNodes( "indexTwo" ) );
Index<Node> indexTwo = db.index().forNodes( "indexTwo" );
verifyConfiguration( db, indexTwo, LuceneIndexProvider.FULLTEXT_CONFIG );
assertTrue( db.index().existsForRelationships( "indexThree" ) );
Index<Relationship> indexThree = db.index().forRelationships( "indexThree" );
verifyConfiguration( db, indexThree, LuceneIndexProvider.EXACT_CONFIG );
db.shutdown();
}
private void verifyConfiguration( GraphDatabaseService db, Index<? extends PropertyContainer> index, Map<String, String> config )
{
assertEquals( config, db.index().getConfiguration( index ) );
}
private void writeFile( InputStream stream, File file ) throws Exception
{
file.delete();
OutputStream out = new FileOutputStream( file );
byte[] bytes = new byte[1024];
int bytesRead = 0;
while ( (bytesRead = stream.read( bytes )) >= 0 )
{
out.write( bytes, 0, bytesRead );
}
out.close();
}
@Test
public void providerGetsFilledInAutomatically()
{
Map<String, String> correctConfig = MapUtil.stringMap( "type", "exact", "provider", "lucene" );
File storeDir = new File( "target/var/index" );
GraphDatabaseService graphDb = new EmbeddedGraphDatabase( storeDir.getPath() );
assertEquals( correctConfig, graphDb.index().getConfiguration( graphDb.index().forNodes( "default" ) ) );
assertEquals( correctConfig, graphDb.index().getConfiguration( graphDb.index().forNodes( "wo-provider", MapUtil.stringMap( "type", "exact" ) ) ) );
assertEquals( correctConfig, graphDb.index().getConfiguration( graphDb.index().forNodes( "w-provider", MapUtil.stringMap( "type", "exact", "provider", "lucene" ) ) ) );
assertEquals( correctConfig, graphDb.index().getConfiguration( graphDb.index().forRelationships( "default" ) ) );
assertEquals( correctConfig, graphDb.index().getConfiguration( graphDb.index().forRelationships( "wo-provider", MapUtil.stringMap( "type", "exact" ) ) ) );
assertEquals( correctConfig, graphDb.index().getConfiguration( graphDb.index().forRelationships( "w-provider", MapUtil.stringMap( "type", "exact", "provider", "lucene" ) ) ) );
graphDb.shutdown();
removeProvidersFromIndexDbFile( storeDir );
graphDb = new EmbeddedGraphDatabase( storeDir.getPath() );
// Getting the index w/o exception means that the provider has been reinstated
assertEquals( correctConfig, graphDb.index().getConfiguration( graphDb.index().forNodes( "default" ) ) );
assertEquals( correctConfig, graphDb.index().getConfiguration( graphDb.index().forNodes( "wo-provider", MapUtil.stringMap( "type", "exact" ) ) ) );
assertEquals( correctConfig, graphDb.index().getConfiguration( graphDb.index().forNodes( "w-provider", MapUtil.stringMap( "type", "exact", "provider", "lucene" ) ) ) );
assertEquals( correctConfig, graphDb.index().getConfiguration( graphDb.index().forRelationships( "default" ) ) );
assertEquals( correctConfig, graphDb.index().getConfiguration( graphDb.index().forRelationships( "wo-provider", MapUtil.stringMap( "type", "exact" ) ) ) );
assertEquals( correctConfig, graphDb.index().getConfiguration( graphDb.index().forRelationships( "w-provider", MapUtil.stringMap( "type", "exact", "provider", "lucene" ) ) ) );
graphDb.shutdown();
removeProvidersFromIndexDbFile( storeDir );
graphDb = new EmbeddedGraphDatabase( storeDir.getPath() );
// Getting the index w/o exception means that the provider has been reinstated
assertEquals( correctConfig, graphDb.index().getConfiguration( graphDb.index().forNodes( "default" ) ) );
assertEquals( correctConfig, graphDb.index().getConfiguration( graphDb.index().forNodes( "wo-provider" ) ) );
assertEquals( correctConfig, graphDb.index().getConfiguration( graphDb.index().forNodes( "w-provider" ) ) );
assertEquals( correctConfig, graphDb.index().getConfiguration( graphDb.index().forRelationships( "default" ) ) );
assertEquals( correctConfig, graphDb.index().getConfiguration( graphDb.index().forRelationships( "wo-provider" ) ) );
assertEquals( correctConfig, graphDb.index().getConfiguration( graphDb.index().forRelationships( "w-provider" ) ) );
graphDb.shutdown();
}
private void removeProvidersFromIndexDbFile( File storeDir )
{
IndexStore indexStore = new IndexStore( storeDir.getPath() );
for ( Class<? extends PropertyContainer> cls : new Class[] {Node.class, Relationship.class} )
{
for ( String name : indexStore.getNames( cls ) )
{
Map<String, String> config = indexStore.get( cls, name );
config = new HashMap<String, String>( config );
config.remove( "provider" );
indexStore.set( Node.class, name, config );
}
}
}
}