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

dk.cloudcreate.essentials.components.eventsourced.aggregates.decider.HandlerResult Maven / Gradle / Ivy

There is a newer version: 0.40.19
Show newest version
/*
 * Copyright 2021-2024 the original author or authors.
 *
 * 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
 *
 *      https://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 dk.cloudcreate.essentials.components.eventsourced.aggregates.decider;

import dk.cloudcreate.essentials.shared.functional.tuple.Either;

import java.util.*;

import static dk.cloudcreate.essentials.shared.FailFast.requireNonNull;
import static dk.cloudcreate.essentials.shared.MessageFormatter.msg;

/**
 * Captures that result of calling a {@link Handler#handle(Object, Object)} for a specific COMMAND and aggregate STATE
* Concrete instances can either be of type {@link Success} or type {@link Error} * * @param The type of Events that can be returned by {@link Handler#handle(Object, Object)} and applied in the {@link StateEvolver#applyEvent(Object, Object)} * @param The type of Error that can be returned by the {@link Handler#handle(Object, Object)} method */ public sealed interface HandlerResult { /** * Did the command handling result in an error? * * @return Did the command handling result in an error? */ boolean isError(); /** * Was the result of the command handling a success? * * @return Was the result of the command handling a success? */ default boolean isSuccess() { return !isError(); } /** * Convert the {@link HandlerResult} to a {@link Success} * * @return the {@link HandlerResult} converted to a {@link Success} * @throws IllegalStateException if the {@link HandlerResult} is an {@link Error} */ default Success asSuccess() { if (isSuccess()) { return (Success) this; } else { throw new IllegalStateException(msg("Can't convert an error to a success. Error: {}", asError())); } } /** * Convert the {@link HandlerResult} to an {@link Error} * * @return the {@link HandlerResult} converted to an {@link Error} * @throws IllegalStateException if the {@link HandlerResult} is an {@link Success} */ default Error asError() { if (isError()) { return (Error) this; } else { throw new IllegalStateException(msg("Can't convert an success to an error. Success: {}", asSuccess())); } } // ---- Test related methods ---- /** * Test oriented method that verify that the {@link HandlerResult} * {@link #isSuccess()} and the {@link Success#events()} contains exactly same events as the events parameter * * @param events the events that we want to verify the {@link Success#events()} contains * @throws IllegalStateException in case the expectations aren't met */ default void shouldSucceedWith(EVENT... events) { shouldSucceedWith(List.of(events)); } /** * Test oriented method that verify that the {@link HandlerResult} * {@link #isSuccess()} and the {@link Success#events()} contains exactly same events as the events parameter * * @param events the events that we want to verify the {@link Success#events()} contains * @throws IllegalStateException in case the expectations aren't met */ default void shouldSucceedWith(List events) { if (isError()) { throw new IllegalStateException(msg("Expected a success, but was a failure: {}", asError().error)); } if (!Objects.equals(asSuccess().events, events)) { throw new IllegalStateException(msg("Expected events {}, but received events: {}", asSuccess().events, events)); } } /** * Test oriented method that verify that the {@link HandlerResult} * {@link #isError()} and the {@link Error#error()} is exactly same as the error parameter * * @param error the error that we want to verify is the same as the {@link Error#error()} * @throws IllegalStateException in case the expectations aren't met */ default void shouldFailWith(ERROR error) { if (isSuccess()) { throw new IllegalStateException(msg("Expected a failure, but was a success: {}", asSuccess().events)); } if (!Objects.equals(asError().error, error)) { throw new IllegalStateException(msg("Expected error {}, but received error: {}", asError().error, error)); } } /** * Error variant of the {@link HandlerResult} * * @param error the error (non-null) that the {@link Handler#handle(Object, Object)} resulted in * @param the type of Error supported by the {@link Handler} * @param the type of Events supported by the {@link Handler} */ record Error(ERROR error) implements HandlerResult { public Error { requireNonNull(error, "No error provided"); } @Override public boolean isError() { return true; } } /** * Success variant of the {@link HandlerResult} * * @param events the (non-null) events that the {@link Handler#handle(Object, Object)} resulted in. Is allowed to be empty * @param the type of Error supported by the {@link Handler} * @param the type of Events supported by the {@link Handler} */ record Success(List events) implements HandlerResult { public Success { requireNonNull(events, "events list was null"); } public Success(EVENT... events) { this(List.of(events)); } @Override public boolean isError() { return false; } } /** * Factory method for returning an ERROR from {@link Handler#handle(Object, Object)} * * @param error the error to return * @param The type of Events that can be returned by {@link Handler#handle(Object, Object)} and applied in the {@link StateEvolver#applyEvent(Object, Object)} * @param The type of Error that can be returned by the {@link Handler#handle(Object, Object)} method * @return An {@link Either} with {@link Either#_1} containing the error */ static HandlerResult.Error error(ERROR error) { requireNonNull(error, "No error provided"); return new HandlerResult.Error<>(error); } /** * Factory method for returning a list of EVENT's from {@link Handler#handle(Object, Object)} * * @param events the events to return (is allowed to be empty) * @param The type of Events that can be returned by {@link Handler#handle(Object, Object)} and applied in the {@link StateEvolver#applyEvent(Object, Object)} * @param The type of Error that can be returned by the {@link Handler#handle(Object, Object)} method * @return An {@link Either} with {@link Either#_2} containing a list of events */ static HandlerResult.Success events(EVENT... events) { return new HandlerResult.Success<>(events); } /** * Factory method for returning a list of EVENT's from {@link Handler#handle(Object, Object)} * * @param events the events to return (is allowed to be empty) * @param The type of Events that can be returned by {@link Handler#handle(Object, Object)} and applied in the {@link StateEvolver#applyEvent(Object, Object)} * @param The type of Error that can be returned by the {@link Handler#handle(Object, Object)} method * @return An {@link Either} with {@link Either#_2} containing a list of events */ static HandlerResult.Success events(List events) { return new HandlerResult.Success<>(events); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy