/* * Copyright (c) 2010-2015. Axon Framework * * 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.axonframework.commandhandling.model; import org.axonframework.commandhandling.CommandMessage; import java.util.Objects; import java.util.function.Consumer; import java.util.function.Function; /** * Interface that describes an aggregate. An aggregate is an isolated tree of entities that is capable of handling * {@link CommandMessage commands}. Implementations of this interface defer the actual handling of commands to a wrapped * instance of type {@code T} or one of its entities. * <p> * When a command is dispatched to an aggregate Axon will load the aggregate instance and invoke the related command * handler method. It is rarely necessary to interact with {@link Aggregate aggregates} directly. Though it is not * recommended it is possible to invoke methods on the wrapped instance using {@link #invoke(Function)} and {@link * #execute(Consumer)}. * * @param <T> The aggregate root type */ public interface Aggregate<T> { /** * Get the String representation of the aggregate's type. This defaults to the simple name of the {@link * #rootType()} unless configured otherwise. * * @return The aggregate's type */ String type(); /** * Get the unique identifier of this aggregate, represented as a String. * * @return The aggregate's identifier as a String */ default String identifierAsString() { return Objects.toString(identifier(), null); } /** * Get the unique identifier of this aggregate * @return The aggregate's identifier */ Object identifier(); /** * Get the aggregate's version. For event sourced aggregates this is identical to the sequence number of the last * applied event. * * @return The aggregate's version */ Long version(); /** * Handle the given {@code commandMessage} on the aggregate root or one of its child entities. * * @param commandMessage The command to be handled by the aggregate * @return The result of command handling. Returns {@code null} in case the command yields no result. * @throws Exception in case one is triggered during command processing */ Object handle(CommandMessage<?> commandMessage) throws Exception; /** * Invoke a method on the underlying aggregate root or one of its instances. Use this over {@link * #execute(Consumer)} to obtain an invocation result, for instance in order to query the aggregate. * <p> * Note that the use of this method is not recommended as aggregates are not meant to be queried. Relying on this * method is commonly a sign of design smell. * * @param invocation The function that performs the actual invocation * @param <R> The type of the result produced by the given invocation * @return The invocation result */ <R> R invoke(Function<T, R> invocation); /** * Execute a method on the underlying aggregate or one of its instances. * <p> * Note that the use of this method is not recommended as the wrapped aggregate instance is not meant to be * exposed. Relying on this method is commonly a sign of design smell. * * @param invocation The function that performs the invocation */ void execute(Consumer<T> invocation); /** * Check if this aggregate has been deleted. This is checked by aggregate repositories when an aggregate is loaded. * In case the repository is asked to load a deleted aggregate the repository will refuse by throwing an {@link * org.axonframework.eventsourcing.AggregateDeletedException}. * * @return {@code true} in case the aggregate was deleted, {@code false} otherwise */ boolean isDeleted(); /** * Get the class type of the wrapped aggregate root that the Aggregate defers to for command handling. * * @return The aggregate root type */ Class<? extends T> rootType(); }