| /* |
| * Copyright (c) 2011, Rickard Öberg. All Rights Reserved. |
| * |
| * 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.library.eventsourcing.domain.source.helper; |
| |
| import java.io.IOException; |
| import java.security.Principal; |
| import org.junit.Test; |
| import org.qi4j.api.activation.ActivatorAdapter; |
| import org.qi4j.api.activation.Activators; |
| import org.qi4j.api.common.UseDefaults; |
| import org.qi4j.api.configuration.Configuration; |
| import org.qi4j.api.entity.EntityComposite; |
| import org.qi4j.api.injection.scope.Service; |
| import org.qi4j.api.injection.scope.This; |
| import org.qi4j.api.mixin.Mixins; |
| import org.qi4j.api.property.Property; |
| import org.qi4j.api.service.ServiceComposite; |
| import org.qi4j.api.service.ServiceReference; |
| import org.qi4j.api.unitofwork.UnitOfWork; |
| import org.qi4j.api.unitofwork.UnitOfWorkCompletionException; |
| import org.qi4j.api.usecase.UsecaseBuilder; |
| import org.qi4j.bootstrap.AssemblyException; |
| import org.qi4j.bootstrap.ImportedServiceDeclaration; |
| import org.qi4j.bootstrap.ModuleAssembly; |
| import org.qi4j.functional.Function; |
| import org.qi4j.io.Output; |
| import org.qi4j.io.Outputs; |
| import org.qi4j.io.Transforms; |
| import org.qi4j.library.eventsourcing.domain.api.DomainEvent; |
| import org.qi4j.library.eventsourcing.domain.api.DomainEventValue; |
| import org.qi4j.library.eventsourcing.domain.api.UnitOfWorkDomainEventsValue; |
| import org.qi4j.library.eventsourcing.domain.factory.CurrentUserUoWPrincipal; |
| import org.qi4j.library.eventsourcing.domain.factory.DomainEventCreationConcern; |
| import org.qi4j.library.eventsourcing.domain.factory.DomainEventFactoryService; |
| import org.qi4j.library.eventsourcing.domain.source.EventSource; |
| import org.qi4j.library.eventsourcing.domain.source.EventStream; |
| import org.qi4j.library.eventsourcing.domain.source.memory.MemoryEventStoreService; |
| import org.qi4j.test.AbstractQi4jTest; |
| import org.qi4j.test.EntityTestAssembler; |
| |
| public class DomainEventTrackerTest |
| extends AbstractQi4jTest |
| { |
| public void assemble( ModuleAssembly module ) throws AssemblyException |
| { |
| new EntityTestAssembler( ).assemble( module ); |
| |
| module.values( DomainEventValue.class, UnitOfWorkDomainEventsValue.class ); |
| module.services( MemoryEventStoreService.class ); |
| module.services( DomainEventFactoryService.class ); |
| module.importedServices( CurrentUserUoWPrincipal.class ).importedBy( ImportedServiceDeclaration.NEW_OBJECT ); |
| module.objects( CurrentUserUoWPrincipal.class ); |
| |
| module.entities( TestEntity.class ).withConcerns( DomainEventCreationConcern.class ); |
| |
| module.services( EventLoggingService.class ).instantiateOnStartup(); |
| module.entities( DomainEventTrackerConfiguration.class ); |
| } |
| |
| @Test |
| public void testDomainEvent() throws UnitOfWorkCompletionException, IOException |
| { |
| UnitOfWork uow = module.newUnitOfWork( UsecaseBuilder.newUsecase( "Change description" )); |
| uow.setMetaInfo( new Principal() |
| { |
| public String getName() |
| { |
| return "administrator"; |
| } |
| }); |
| |
| TestEntity entity = uow.newEntity( TestEntity.class ); |
| entity.changeDescription( "New description" ); |
| uow.complete(); |
| |
| try |
| { |
| Thread.sleep( 5000 ); |
| } catch (InterruptedException e) |
| { |
| e.printStackTrace(); |
| } |
| } |
| |
| @Mixins( TestEntity.Mixin.class ) |
| public interface TestEntity |
| extends EntityComposite |
| { |
| @UseDefaults |
| Property<String> description(); |
| |
| @DomainEvent |
| void changeDescription( String newName ); |
| |
| abstract class Mixin |
| implements TestEntity |
| { |
| public void changeDescription( String newName ) |
| { |
| description().set( newName ); |
| } |
| } |
| } |
| |
| @Mixins(EventLoggingService.Mixin.class) |
| @Activators( EventLoggingService.Activator.class ) |
| public interface EventLoggingService |
| extends ServiceComposite, Configuration<DomainEventTrackerConfiguration> |
| { |
| |
| void startTracker(); |
| |
| void stopTracker(); |
| |
| public class Activator |
| extends ActivatorAdapter<ServiceReference<EventLoggingService>> |
| { |
| |
| @Override |
| public void afterActivation( ServiceReference<EventLoggingService> activated ) |
| throws Exception |
| { |
| activated.get().startTracker(); |
| } |
| |
| @Override |
| public void beforePassivation( ServiceReference<EventLoggingService> passivating ) |
| throws Exception |
| { |
| passivating.get().stopTracker(); |
| } |
| |
| } |
| |
| public abstract class Mixin implements EventLoggingService |
| { |
| DomainEventTracker tracker; |
| |
| @This |
| Configuration<DomainEventTrackerConfiguration> config; |
| |
| @Service |
| EventStream eventStream; |
| |
| @Service |
| EventSource eventSource; |
| |
| public void startTracker() |
| { |
| config.get().enabled().set( true ); |
| |
| Output<UnitOfWorkDomainEventsValue,RuntimeException> map = Transforms.map( new Function<UnitOfWorkDomainEventsValue, String>() |
| { |
| public String map( UnitOfWorkDomainEventsValue unitOfWorkDomainEventsValue ) |
| { |
| return unitOfWorkDomainEventsValue.toString(); |
| } |
| }, Outputs.systemOut() ); |
| tracker = new DomainEventTracker(eventStream, eventSource, config, map); |
| |
| tracker.start(); |
| } |
| |
| public void stopTracker() |
| { |
| tracker.stop(); |
| } |
| } |
| } |
| } |