/* Copyright 2008 Rickard Öberg.
*
* Licensed 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.qi4j.entitystore.jgroups;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import org.junit.Test;
import org.junit.Ignore;
import org.qi4j.api.common.Optional;
import org.qi4j.api.entity.EntityBuilder;
import org.qi4j.api.entity.EntityComposite;
import org.qi4j.api.entity.association.Association;
import org.qi4j.api.entity.association.ManyAssociation;
import org.qi4j.api.property.Immutable;
import org.qi4j.api.property.Property;
import org.qi4j.api.unitofwork.NoSuchEntityException;
import org.qi4j.api.unitofwork.UnitOfWork;
import org.qi4j.api.unitofwork.UnitOfWorkCompletionException;
import org.qi4j.api.value.ValueBuilder;
import org.qi4j.api.value.ValueComposite;
import org.qi4j.bootstrap.AssemblyException;
import org.qi4j.bootstrap.ModuleAssembly;
import org.qi4j.bootstrap.SingletonAssembler;
import org.qi4j.spi.uuid.UuidIdentityGeneratorService;
import org.qi4j.test.AbstractQi4jTest;
/**
* Test of JGroups EntityStore backend.
*/
public class JGroupsEntityStoreTest
extends AbstractQi4jTest
{
public void assemble( ModuleAssembly module ) throws AssemblyException
{
module.addServices( UuidIdentityGeneratorService.class );
module.addEntities( TestEntity.class );
module.addValues( TestValue.class );
module.addServices( JGroupsEntityStoreService.class );
}
@Test
@Ignore
public void whenNewEntityThenFindInReplica()
throws Exception
{
// Create first app
SingletonAssembler app1 = new SingletonAssembler()
{
public void assemble( ModuleAssembly module ) throws AssemblyException
{
module.addServices( JGroupsEntityStoreService.class, UuidIdentityGeneratorService.class ).instantiateOnStartup();
module.addEntities( TestEntity.class );
}
};
// Create second app
SingletonAssembler app2 = new SingletonAssembler()
{
public void assemble( ModuleAssembly module ) throws AssemblyException
{
module.addServices( JGroupsEntityStoreService.class, UuidIdentityGeneratorService.class ).instantiateOnStartup();
module.addEntities( TestEntity.class );
}
};
// Create entity in app 1
System.out.println( "Create entity" );
UnitOfWork app1Unit = app1.unitOfWorkFactory().newUnitOfWork();
EntityBuilder<TestEntity> builder = app1Unit.newEntityBuilder( TestEntity.class );
TestEntity instance = builder.instance();
instance.name().set( "Foo" );
instance = builder.newInstance();
app1Unit.complete();
// Thread.sleep( 5000 );
// Find entity in app 2
System.out.println( "Find entity" );
UnitOfWork app2Unit = app2.unitOfWorkFactory().newUnitOfWork();
instance = app2Unit.get( instance );
System.out.println( instance.name() );
app2Unit.discard();
}
@Test
@Ignore
public void whenNewEntityThenCanFindEntity()
throws Exception
{
try
{
UnitOfWork unitOfWork = unitOfWorkFactory.newUnitOfWork();
try
{
TestEntity instance = createEntity( unitOfWork );
unitOfWork.complete();
// Find entity
unitOfWork = unitOfWorkFactory.newUnitOfWork();
instance = unitOfWork.get( instance );
// Check state
assertThat( "property has correct value", instance.name().get(), equalTo( "Test" ) );
assertThat( "property has correct value", instance.unsetName().get(), equalTo( null ) );
assertThat( "association has correct value", instance.association().get(), equalTo( instance ) );
assertThat( "manyAssociation has correct value", instance.manyAssociation().iterator().next(), equalTo( instance ) );
unitOfWork.discard();
}
catch( UnitOfWorkCompletionException e )
{
unitOfWork.discard();
throw e;
}
catch( NoSuchEntityException e )
{
unitOfWork.discard();
throw e;
}
catch( RuntimeException e )
{
unitOfWork.discard();
throw e;
}
}
catch( Exception e )
{
e.printStackTrace();
}
}
@Test
@Ignore
public void whenRemovedEntityThenCannotFindEntity()
throws Exception
{
UnitOfWork unitOfWork = unitOfWorkFactory.newUnitOfWork();
try
{
TestEntity newInstance = createEntity( unitOfWork );
String identity = newInstance.identity().get();
unitOfWork.complete();
// Remove entity
unitOfWork = unitOfWorkFactory.newUnitOfWork();
TestEntity instance = unitOfWork.get( newInstance );
unitOfWork.remove( instance );
unitOfWork.complete();
// Find entity
unitOfWork = unitOfWorkFactory.newUnitOfWork();
try
{
instance = unitOfWork.get( TestEntity.class, identity );
fail( "Should not be able to find entity" );
}
catch( NoSuchEntityException e )
{
// Ok!
}
unitOfWork.discard();
}
catch( UnitOfWorkCompletionException e )
{
unitOfWork.discard();
throw e;
}
catch( NoSuchEntityException e )
{
unitOfWork.discard();
throw e;
}
catch( RuntimeException e )
{
unitOfWork.discard();
throw e;
}
}
protected TestEntity createEntity( UnitOfWork unitOfWork )
throws UnitOfWorkCompletionException
{
// Create entity
EntityBuilder<TestEntity> builder = unitOfWork.newEntityBuilder( TestEntity.class );
TestEntity instance = builder.newInstance();
String id = instance.identity().get();
instance.name().set( "Test" );
instance.association().set( instance );
ValueBuilder<TestValue> valueBuilder = valueBuilderFactory.newValueBuilder( TestValue.class );
TestValue state = valueBuilder.prototype();
state.someValue().set( "Foo" );
state.otherValue().set( 5 );
TestValue value = valueBuilder.newInstance();
instance.valueProperty().set( value );
instance.manyAssociation().add( instance );
return instance;
}
public interface TestEntity
extends EntityComposite
{
@Optional Property<String> name();
@Optional Property<String> unsetName();
@Optional Property<TestValue> valueProperty();
@Optional Association<TestEntity> association();
@Optional Association<TestEntity> unsetAssociation();
ManyAssociation<TestEntity> manyAssociation();
}
public interface TestValue extends ValueComposite
{
@Immutable Property<String> someValue();
@Immutable Property<Integer> otherValue();
}
}