diff options
Diffstat (limited to 'eaaf_core/src/main/java/at/gv/egiz/eaaf/core')
8 files changed, 165 insertions, 65 deletions
diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/data/ErrorConfig.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/data/ErrorConfig.java index b9cacb1c..5f1d0976 100644 --- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/data/ErrorConfig.java +++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/data/ErrorConfig.java @@ -2,6 +2,9 @@ package at.gv.egiz.eaaf.core.impl.data; import java.util.List; +import com.fasterxml.jackson.annotation.JsonSetter; +import com.fasterxml.jackson.annotation.Nulls; + import at.gv.egiz.eaaf.core.impl.idp.auth.services.IErrorService.ActionType; import lombok.AllArgsConstructor; import lombok.Builder; @@ -44,6 +47,12 @@ public class ErrorConfig { @Builder.Default private Boolean useInternalAsExternal = false; + @Getter + @Setter + @Builder.Default + @JsonSetter(nulls = Nulls.SKIP) + private Boolean writeThrowable = true; + /** * Get type of error-handling flow. * diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/AbstractAuthenticationManager.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/AbstractAuthenticationManager.java index 76bc09e6..3d0d2a3b 100644 --- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/AbstractAuthenticationManager.java +++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/AbstractAuthenticationManager.java @@ -379,7 +379,7 @@ public abstract class AbstractAuthenticationManager implements IAuthenticationMa final Throwable taskCause = cause.getCause(); if (taskCause != null && taskCause instanceof EaafException) { final EaafException moaTaskCause = (EaafException) taskCause; - log.info(taskCause.getMessage(), taskCause); + log.info(taskCause.getMessage()); throw moaTaskCause; } diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/DefaultErrorService.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/DefaultErrorService.java index cd89f8a5..c9606026 100644 --- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/DefaultErrorService.java +++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/DefaultErrorService.java @@ -105,6 +105,10 @@ public class DefaultErrorService implements IErrorService { @Getter private LogLevel logLevel; + @Getter + @Builder.Default + private boolean writeThrowable = true; + @Override public Map<String, String> getAdditionalGuiModelElements() { return Collections.emptyMap(); diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/IErrorService.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/IErrorService.java index 45b1cfe8..d6d310a5 100644 --- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/IErrorService.java +++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/IErrorService.java @@ -157,6 +157,13 @@ public interface IErrorService { Throwable getThrowable(); /** + * Flag that indicates if stake-trace should be logged for that error. + * + * @return <code>true</code> in case of log stake-trace, otherwise false + */ + boolean isWriteThrowable(); + + /** * Get the log-level for this internal errorId. * * @return Level to Log the error diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/ProtocolAuthenticationService.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/ProtocolAuthenticationService.java index 6de2f94a..00768519 100644 --- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/ProtocolAuthenticationService.java +++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/ProtocolAuthenticationService.java @@ -326,29 +326,47 @@ public class ProtocolAuthenticationService implements IProtocolAuthenticationSer } private void logExceptionToTechnicalLog(IHandleData errorData) { - // In case of a TaskExecutionException, which is only a container for - // process-errors, - // extract internal exception + if (errorData.isWriteThrowable()) { + if (!(errorData.getThrowable() instanceof EaafException) + || LogLevel.ERROR.equals(errorData.getLogLevel())) { + log.error(errorData.getPreFormatedErrorMessage(), errorData.getThrowable()); - // Log exception - if (!(errorData.getThrowable() instanceof EaafException) - || LogLevel.ERROR.equals(errorData.getLogLevel())) { - log.error(errorData.getPreFormatedErrorMessage(), errorData.getThrowable()); + } else if (LogLevel.WARN.equals(errorData.getLogLevel())) { + log.warn(errorData.getPreFormatedErrorMessage(), errorData.getThrowable()); - } else if (LogLevel.WARN.equals(errorData.getLogLevel())) { - log.warn(errorData.getPreFormatedErrorMessage(), errorData.getThrowable()); + } else if (LogLevel.INFO.equals(errorData.getLogLevel())) { + log.info(errorData.getPreFormatedErrorMessage(), errorData.getThrowable()); - } else if (LogLevel.INFO.equals(errorData.getLogLevel())) { - log.info(errorData.getPreFormatedErrorMessage(), errorData.getThrowable()); + } else if (LogLevel.DEBUG.equals(errorData.getLogLevel())) { + log.debug(errorData.getPreFormatedErrorMessage(), errorData.getThrowable()); - } else if (LogLevel.DEBUG.equals(errorData.getLogLevel())) { - log.debug(errorData.getPreFormatedErrorMessage(), errorData.getThrowable()); + } else { + log.warn("Get unsupported LogLevelType: {}. Use {} as default", + errorData.getLogLevel(), LogLevel.ERROR); + log.error(errorData.getPreFormatedErrorMessage(), errorData.getThrowable()); + + } } else { - log.warn("Get unsupported LogLevelType: {}. Use {} as default", - errorData.getLogLevel(), LogLevel.ERROR); - log.error(errorData.getPreFormatedErrorMessage(), errorData.getThrowable()); + if (!(errorData.getThrowable() instanceof EaafException) + || LogLevel.ERROR.equals(errorData.getLogLevel())) { + log.error(errorData.getPreFormatedErrorMessage()); + + } else if (LogLevel.WARN.equals(errorData.getLogLevel())) { + log.warn(errorData.getPreFormatedErrorMessage()); + + } else if (LogLevel.INFO.equals(errorData.getLogLevel())) { + log.info(errorData.getPreFormatedErrorMessage()); + } else if (LogLevel.DEBUG.equals(errorData.getLogLevel())) { + log.debug(errorData.getPreFormatedErrorMessage()); + + } else { + log.warn("Get unsupported LogLevelType: {}. Use {} as default", + errorData.getLogLevel(), LogLevel.ERROR); + log.error(errorData.getPreFormatedErrorMessage()); + + } } } @@ -566,18 +584,18 @@ public class ProtocolAuthenticationService implements IProtocolAuthenticationSer // write error message writeHtmlErrorResponse(req, resp, e.getMessage(), internalErrorCode, e instanceof EaafException ? ((EaafException) e).getParams() : null, - statusMessager.mapInternalErrorToExternalError(internalErrorCode), errorData); + errorTicketService.getExternalCodeFromInternal(internalErrorCode), errorData); } else if (e instanceof EaafException) { // send HTML formated error message writeHtmlErrorResponse(req, resp, e.getMessage(), internalErrorCode, ((EaafException) e).getParams(), - statusMessager.mapInternalErrorToExternalError(internalErrorCode), errorData); + errorTicketService.getExternalCodeFromInternal(internalErrorCode), errorData); } else { // write generic message for general exceptions final String msg = statusMessager.getMessage(IStatusMessenger.CODES_INTERNAL_ERROR_GENERIC, null); writeHtmlErrorResponse(req, resp, msg, internalErrorCode, null, - statusMessager.mapInternalErrorToExternalError(internalErrorCode), errorData); + errorTicketService.getExternalCodeFromInternal(internalErrorCode), errorData); } } diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/TicketErrorService.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/TicketErrorService.java index 39262f70..bb0e9928 100644 --- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/TicketErrorService.java +++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/auth/services/TicketErrorService.java @@ -85,6 +85,7 @@ public abstract class TicketErrorService implements IErrorService { return HandleData.builder() .throwable(throwable) + .writeThrowable(errorFlowConfig.getWriteThrowable()) .internalErrorCode(internalErrorId) .actionType(errorHandlingFlow) .logLevel(LogLevel.fromString(errorFlowConfig.getLogLevel())) @@ -154,7 +155,7 @@ public abstract class TicketErrorService implements IErrorService { return modelExtensionHandlers.stream() .map(el -> el.elementsForErrorModel(protocolRequest)) .flatMap(m -> m.entrySet().stream()) - .collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, Map.Entry::getValue)); + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); } @@ -260,6 +261,10 @@ public abstract class TicketErrorService implements IErrorService { private LogLevel logLevel; @Getter + @Builder.Default + private boolean writeThrowable = true; + + @Getter private Map<String, String> additionalGuiModelElements; public String getPreFormatedErrorMessage() { diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/protocols/RequestImpl.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/protocols/RequestImpl.java index 27b032e3..fcb7cc27 100644 --- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/protocols/RequestImpl.java +++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/controller/protocols/RequestImpl.java @@ -112,7 +112,7 @@ public abstract class RequestImpl implements IRequest, Serializable { private boolean needUserConsent = false; private boolean currentlyInIframe = false; - + private final Map<String, Object> genericDataStorage = new HashMap<>(); /** @@ -132,9 +132,10 @@ public abstract class RequestImpl implements IRequest, Serializable { /** * Initialize this pendingRequest object. * - * @param req {@link HttpServletRequest} - * @param authConfig {@link IConfiguration} - * @param transactionId Unique ID for technical log correlation that should be used in this pendingRequest + * @param req {@link HttpServletRequest} + * @param authConfig {@link IConfiguration} + * @param transactionId Unique ID for technical log correlation that should be + * used in this pendingRequest * @throws EaafException * */ @@ -147,11 +148,13 @@ public abstract class RequestImpl implements IRequest, Serializable { /** * Initialize this pendingRequest object. * - * @param req {@link HttpServletRequest} - * @param authConfig {@link IConfiguration} - * @param transactionId Unique ID for technical log correlation that should be used in this pendingRequest - * @param piiTransactionId Unique ID for PII data correlation that should be used in this pendingRequest - * for logging. If 'null' a new one will be generated + * @param req {@link HttpServletRequest} + * @param authConfig {@link IConfiguration} + * @param transactionId Unique ID for technical log correlation that should + * be used in this pendingRequest + * @param piiTransactionId Unique ID for PII data correlation that should be + * used in this pendingRequest for logging. If 'null' a + * new one will be generated * * @throws EaafException * @@ -246,7 +249,6 @@ public abstract class RequestImpl implements IRequest, Serializable { this.passiv = passiv; } - public final void setForce(final boolean force) { this.force = force; } @@ -346,7 +348,7 @@ public abstract class RequestImpl implements IRequest, Serializable { /** * Inject Service-Provider configuration into that authentication process. - * + * * @param spConfig SP configuration */ @JsonIgnore @@ -381,8 +383,8 @@ public abstract class RequestImpl implements IRequest, Serializable { } /** - * Set an unique transaction identifier to correlate technical logging - * in one single transaction. + * Set an unique transaction identifier to correlate technical logging in one + * single transaction. * * @param id Unique identifier */ @@ -392,8 +394,8 @@ public abstract class RequestImpl implements IRequest, Serializable { } /** - * Set an unique session identifier to correlate technical logging over a set of transactions, - * like SSO as one example. + * Set an unique session identifier to correlate technical logging over a set of + * transactions, like SSO as one example. * * @param id Unique identifier */ @@ -405,7 +407,9 @@ public abstract class RequestImpl implements IRequest, Serializable { /** * Set an unique transaction identifier to correlate PII related data. * - * <p>This identifier will be not used for technical logging.</p> + * <p> + * This identifier will be not used for technical logging. + * </p> * * @param id Unique identifier */ @@ -414,7 +418,6 @@ public abstract class RequestImpl implements IRequest, Serializable { } - public void setProcessInstanceId(final String id) { this.processInstanceId = id; @@ -499,44 +502,35 @@ public abstract class RequestImpl implements IRequest, Serializable { @Override public void setProcessInFrame(boolean flag) { this.currentlyInIframe = flag; - - } - - @Override - public final Object getRawData(final String key) { - if (StringUtils.isNotEmpty(key)) { - return objectSaveJsonDeserialization(genericDataStorage.get(key)); - } - - log.info("Can not load generic request-data with key='null'"); - return null; } @Override - public final <T> T getRawData(final String key, final Class<T> clazz) { + public final Object getRawData(final String key) { if (StringUtils.isNotEmpty(key)) { final Object data = genericDataStorage.get(key); - if (data == null) { return null; } + return objectSaveJsonDeserialization(genericDataStorage.get(key)); - try { - Object deserializedObject = objectSaveJsonDeserialization(data); - return deserializedObject != null ? (T) deserializedObject : null; - - } catch (final Exception e) { - log.warn("Generic request-data object can not be casted to requested type", e); - return null; - - } } log.info("Can not load generic request-data with key='null'"); return null; + } + + @Override + public final <T> T getRawData(final String key, final Class<T> clazz) { + try { + final Object deserializedObject = getRawData(key); + return deserializedObject != null ? (T) deserializedObject : null; + } catch (final Exception e) { + log.warn("Generic request-data object can not be casted to requested type", e); + return null; + } } @Override @@ -583,6 +577,7 @@ public abstract class RequestImpl implements IRequest, Serializable { } + @Override public final void removeRawDataFromTransaction(String key) { genericDataStorage.remove(key); @@ -595,7 +590,7 @@ public abstract class RequestImpl implements IRequest, Serializable { .clazzzType(object.getClass().getName()) .build()); - } catch (EaafJsonMapperException e) { + } catch (final EaafJsonMapperException e) { throw new EaafStorageException("Can no serialize object to JSON", e); } @@ -604,9 +599,9 @@ public abstract class RequestImpl implements IRequest, Serializable { private Object objectSaveJsonDeserialization(Object data) { try { if (data instanceof String) { - RawDataHolder holder = (RawDataHolder) DefaultJsonMapper.deserialize( + final RawDataHolder holder = (RawDataHolder) DefaultJsonMapper.deserialize( (String) data, RawDataHolder.class); - Class<?> clz = Class.forName(holder.getClazzzType()); + final Class<?> clz = Class.forName(holder.getClazzzType()); return DefaultJsonMapper.deserialize(holder.getObject(), clz); } else { diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/DefaultJsonMapper.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/DefaultJsonMapper.java index 8303e860..f5521274 100644 --- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/DefaultJsonMapper.java +++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/DefaultJsonMapper.java @@ -1,6 +1,8 @@ package at.gv.egiz.eaaf.core.impl.utils; import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; import com.fasterxml.jackson.annotation.PropertyAccessor; @@ -9,10 +11,10 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.Module; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.type.TypeFactory; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import at.gv.egiz.eaaf.core.exceptions.EaafJsonMapperException; import lombok.Getter; @@ -27,6 +29,9 @@ import lombok.extern.slf4j.Slf4j; @Slf4j public final class DefaultJsonMapper { + private static final String JAVA_TIME_MODULE_CLASS = "com.fasterxml.jackson.datatype.jsr310.JavaTimeModule"; + private static final String JODA_TIME_MODULE_CLASS = "com.fasterxml.jackson.datatype.joda.JodaModule"; + @Getter private static final ObjectMapper jsonMapper = new ObjectMapper(); @@ -39,7 +44,9 @@ public final class DefaultJsonMapper { jsonMapper.setVisibility(PropertyAccessor.GETTER, Visibility.PUBLIC_ONLY); jsonMapper.setVisibility(PropertyAccessor.IS_GETTER, Visibility.PUBLIC_ONLY); - jsonMapper.registerModule(new JavaTimeModule()); + registerModuleIfAvailable(JAVA_TIME_MODULE_CLASS); + registerModuleIfAvailable(JODA_TIME_MODULE_CLASS); + jsonMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); } @@ -101,6 +108,61 @@ public final class DefaultJsonMapper { throw new EaafJsonMapperException(e.getMessage(), e); } + } + + private static void registerModuleIfAvailable(String fullModuleClasspath) { + Module module = checkAndLoadModule(fullModuleClasspath); + if (module != null) { + jsonMapper.registerModule(module); + log.info("Register Jackson module: {}", module.getModuleName()); + + } else { + log.debug("Skipping Jackson module not on classpath: {}", fullModuleClasspath); + + } + } + + private static Module checkAndLoadModule(String fullModuleClasspath) { + Class<?> clazz = getModuleClass(fullModuleClasspath); + if (clazz != null) { + return getModuleInstance(clazz); + } + + return null; + } + + private static Module getModuleInstance(Class<?> clazz) { + try { + final Constructor<?> constructor = clazz.getConstructor((Class[]) null); + if (constructor != null) { + log.trace("Found method: {} for class:{}. Creating instanze .... ", + constructor.getName(), clazz.getName()); + final Object rawModule = constructor.newInstance(null); + return rawModule instanceof Module ? (Module) rawModule : null; + } else { + log.warn("Find module:{}, no supported constructor found!", clazz.getName()); + + } + + } catch (NoSuchMethodException | SecurityException | IllegalAccessException + | IllegalArgumentException | InvocationTargetException | InstantiationException e) { + log.debug("Can not create instanze of Jackson module: {}. Reason: {}", clazz.getName(), e.getMessage()); + log.trace("Detailed error", e); + + } + return null; + + } + + private static Class<?> getModuleClass(String fullClassName) { + try { + return Class.forName(fullClassName); + + } catch (final ClassNotFoundException e1) { + log.debug("No {} implemenation in ClassPath. Jackson module will not be available", fullClassName); + return null; + + } } } |