SendMessageRetryablePredicates.java
package fr.sii.ogham.core.builder.configurer;
import static fr.sii.ogham.core.util.ExceptionUtils.fatalJvmError;
import static fr.sii.ogham.core.util.ExceptionUtils.hasAnyCause;
import java.util.function.Predicate;
import fr.sii.ogham.core.exception.InvalidMessageException;
import fr.sii.ogham.core.exception.filler.FillMessageException;
import fr.sii.ogham.core.exception.handler.NoContentException;
import fr.sii.ogham.core.exception.handler.TemplateNotFoundException;
import fr.sii.ogham.core.exception.handler.TemplateParsingFailedException;
import fr.sii.ogham.core.exception.mimetype.MimeTypeDetectionException;
import fr.sii.ogham.core.exception.resource.ResourceResolutionException;
import fr.sii.ogham.core.exception.template.ContextException;
import fr.sii.ogham.core.exception.template.EngineDetectionException;
import fr.sii.ogham.core.exception.template.ParseException;
import fr.sii.ogham.core.exception.util.BeanException;
import fr.sii.ogham.core.util.ExceptionUtils;
/**
* Predicate that skip retry if one of theses condition is met:
*
* <ul>
* <li>The error is a JVM error that should not be ignored</li>
* <li>If the error is due to a preparation error (not sending). In this case,
* retrying will result in the same behavior so it will fail again:
* <ul>
* <li>It is a parsing error</li>
* <li>The message in not valid</li>
* <li>A resource associated to the message can't be resolved</li>
* <li>The mimetype of a resource couldn't be determined</li>
* </ul>
* </li>
* </ul>
*
* <p>
* In other situations, the message may be sent again.
*
*
* @author Aurélien Baudet
*
*/
public final class SendMessageRetryablePredicates {
private SendMessageRetryablePredicates() {
super();
}
/**
* Predicate that skip retry if one of theses condition is met:
*
* <ul>
* <li>The error is a JVM error that should not be ignored</li>
* <li>If the error is due to a preparation error (not sending). In this
* case, retrying will result in the same behavior so it will fail again:
* <ul>
* <li>It is a parsing error</li>
* <li>The message in not valid</li>
* <li>A resource associated to the message can't be resolved</li>
* <li>The mimetype of a resource couldn't be determined</li>
* </ul>
* </li>
* </ul>
*
* <p>
* In other situations, the message may be sent again.
*
* @param error
* the error to analyze
* @return true if the message can be sent again
*/
@SuppressWarnings("squid:S1126")
public static boolean canResendMessage(Throwable error) {
if (fatalJvmError(error) || isMessagePreparationError(error)) {
return false;
}
if (hasAnyCause(error, ExceptionUtils::fatalJvmError) || hasAnyCause(error, SendMessageRetryablePredicates::isMessagePreparationError)) {
return false;
}
return true;
}
/**
* Checks is raised during preparation of the message.
*
* <p>
* The error may be due to:
* <ul>
* <li>Either a parsing error</li>
* <li>Or the message in not valid</li>
* <li>Or a resource can't be resolved</li>
* <li>Or the mimetype of a resource couldn't be determined</li>
* </ul>
*
* <p>
* In these cases, retrying will always give the same result so there is no
* point in retrying.
*
* @param error
* the error to analyze
* @return true if the error is raised during preparation of the message
*/
public static boolean isMessagePreparationError(Throwable error) {
// @formatter:off
return parsingFailed(error)
|| messageIsInvalid(error)
|| resourceIsUnresolved(error)
|| mimetypeIsUndetectable(error)
|| developerError(error);
// @formatter:on
}
/**
* Indicates if the error is raised during template parsing.
*
* @param error
* the error to analyze
* @return true if it is a parsing error
*/
public static boolean parsingFailed(Throwable error) {
// @formatter:off
return error instanceof ParseException
|| error instanceof BeanException
|| error instanceof EngineDetectionException
|| error instanceof ContextException
|| error instanceof TemplateParsingFailedException
|| error instanceof TemplateNotFoundException
|| error instanceof NoContentException;
// @formatter:on
}
/**
* Indicates if the error is raised because the message is invalid.
*
* @param error
* the error to analyze
* @return true if the message is invalid
*/
public static boolean messageIsInvalid(Throwable error) {
// @formatter:off
return error instanceof InvalidMessageException
|| error instanceof FillMessageException;
// @formatter:on
}
/**
* Indicates if the error is raised because a resource can't be resolved.
*
* @param error
* the error to analyze
* @return true if a resource can't be resolved
*/
public static boolean resourceIsUnresolved(Throwable error) {
return error instanceof ResourceResolutionException;
}
/**
* Indicates if the error is raised because a resource mimetype can't be
* determined.
*
* @param error
* the error to analyze
* @return true if a resource mimetype can't be determined
*/
public static boolean mimetypeIsUndetectable(Throwable error) {
return error instanceof MimeTypeDetectionException;
}
/**
* Indicates if the error is raised because the developer has misconfigured
* or has used an illegal value ( {@link IllegalArgumentException},
* {@link NullPointerException}, ...).
*
* @param error
* the error to analyze
* @return true if developer has used an illegal value
*/
public static boolean developerError(Throwable error) {
// @formatter:off
return error instanceof IllegalArgumentException
|| error instanceof NullPointerException;
// @formatter:on
}
/**
* Predicate that skip retry if one of theses condition is met:
*
* <ul>
* <li>The error is a JVM error that should not be ignored</li>
* <li>If the error is due to a preparation error (not sending). In this
* case, retrying will result in the same behavior so it will fail again:
* <ul>
* <li>It is a parsing error</li>
* <li>The message in not valid</li>
* <li>A resource associated to the message can't be resolved</li>
* <li>The mimetype of a resource couldn't be determined</li>
* </ul>
* </li>
* </ul>
*
* <p>
* In other situations, the message may be sent again.
*
* @return the predicate
*/
public static Predicate<Throwable> canResendMessage() {
return SendMessageRetryablePredicates::canResendMessage;
}
}