All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.elder.sourcerer.spring.SourcererCommandConfiguration Maven / Gradle / Ivy

package org.elder.sourcerer.spring;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.elder.sourcerer.AggregateProjection;
import org.elder.sourcerer.AggregateRepository;
import org.elder.sourcerer.CommandFactory;
import org.elder.sourcerer.CommandPostProcessor;
import org.elder.sourcerer.DefaultAggregateRepository;
import org.elder.sourcerer.DefaultCommandFactory;
import org.elder.sourcerer.MetadataDecorator;
import org.elder.sourcerer.EventRepository;
import org.elder.sourcerer.MetadataDecoratorCommandPostProcessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Base class for Spring Java configurations defining all required components surrounding a given
 * event and aggregate type, i.e. aggregate repository, event repository, command factory and
 * subscription factory.
 * 

* Components are lazy loaded so as to not use any resources unless actually used in the system *

* To use this class, create a subclass with the given concrete types and any other customizations, * placed in the component scan path of your Spring application. You must also separately configure * a EventRepositoryFactory. */ public class SourcererCommandConfiguration extends SourcererEventConfiguration { private final Class stateType; private final AggregateProjection projection; @Autowired(required = false) private List metadataDecorators; @Autowired private ObjectMapper objectMapper; protected SourcererCommandConfiguration( final Class eventType, final Class stateType, final AggregateProjection projection) { super(eventType); this.stateType = stateType; this.projection = projection; } @Bean @Lazy @Scope(BeanDefinition.SCOPE_SINGLETON) public AggregateRepository getAggregateRepository( final EventRepository eventRepository) { return new DefaultAggregateRepository<>(eventRepository, projection, this::resolveType); } @Bean @Lazy @Scope(BeanDefinition.SCOPE_SINGLETON) public CommandFactory getCommandFactory( final AggregateRepository aggregateRepository) { List commandPostProcessors = new ArrayList<>(); if (metadataDecorators != null) { for (MetadataDecorator metadataDecorator : metadataDecorators) { commandPostProcessors.add( new MetadataDecoratorCommandPostProcessor(metadataDecorator)); } } return new DefaultCommandFactory<>(aggregateRepository, commandPostProcessors); } public String resolveType(final TEvent event) { Map jsonMap = objectMapper.convertValue(event, Map.class); if (!jsonMap.containsKey("type")) { throw new IllegalArgumentException( "Event does not appear to use polymorphic Jackson serialization" + ", override resolveType() to provide a different implementation"); } return (String) jsonMap.get("type"); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy