[SYNCOPE-1144] Minor changes and cleanup
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/cb57c5ad Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/cb57c5ad Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/cb57c5ad Branch: refs/heads/master Commit: cb57c5ad20bcd90efe09d0666f27ab151aa4b00c Parents: d7fbfe4 Author: Francesco Chicchiriccò <[email protected]> Authored: Thu Jul 13 16:07:44 2017 +0200 Committer: Francesco Chicchiriccò <[email protected]> Committed: Thu Jul 13 16:07:53 2017 +0200 ---------------------------------------------------------------------- .../common/lib/types/AuditLoggerName.java | 10 ++- .../core/logic/AbstractAuditAppender.java | 1 + .../syncope/core/logic/AuditAppender.java | 51 ------------ .../core/logic/DefaultAuditAppender.java | 54 ------------- .../core/logic/DefaultRewriteAuditAppender.java | 64 ---------------- .../apache/syncope/core/logic/LoggerLogic.java | 52 ++++++------- .../core/logic/PassThroughRewritePolicy.java | 41 ---------- .../syncope/core/logic/audit/AuditAppender.java | 52 +++++++++++++ .../core/logic/audit/DefaultAuditAppender.java | 54 +++++++++++++ .../audit/DefaultRewriteAuditAppender.java | 64 ++++++++++++++++ .../audit/PassThroughAuditRewritePolicy.java | 43 +++++++++++ .../init/ClassPathScanImplementationLookup.java | 2 +- .../syncope/core/logic/init/LoggerAccessor.java | 14 ++-- .../syncope/core/logic/init/LoggerLoader.java | 50 ++++++------ .../provisioning/java/AuditManagerImpl.java | 16 +--- .../reference/SyslogRewriteAuditAppender.java | 2 +- .../core/reference/TestFileAuditAppender.java | 2 +- .../reference/TestFileRewriteAuditAppender.java | 20 ++--- .../apache/syncope/fit/core/LoggerITCase.java | 81 ++++++++++---------- .../reference-guide/concepts/audit.adoc | 79 +++++++++---------- .../workingwithapachesyncope/customization.adoc | 7 +- 21 files changed, 375 insertions(+), 384 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/syncope/blob/cb57c5ad/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditLoggerName.java ---------------------------------------------------------------------- diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditLoggerName.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditLoggerName.java index 9c071b8..6fc1ab0 100644 --- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditLoggerName.java +++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/AuditLoggerName.java @@ -34,6 +34,14 @@ public class AuditLoggerName extends AbstractBaseBean { private static final long serialVersionUID = -647989486671786839L; + public static String getAuditLoggerName(final String domain) { + return LoggerType.AUDIT.getPrefix() + "." + domain; + } + + public static String getAuditEventLoggerName(final String domain, final String loggerName) { + return domain + "." + loggerName; + } + private final AuditElements.EventCategoryType type; private final String category; @@ -105,7 +113,7 @@ public class AuditLoggerName extends AbstractBaseBean { eventCategory.getKey().getCategory(), eventCategory.getKey().getSubcategory(), eventCategory.getKey().getEvents().isEmpty() - ? StringUtils.EMPTY : eventCategory.getKey().getEvents().iterator().next(), + ? StringUtils.EMPTY : eventCategory.getKey().getEvents().iterator().next(), eventCategory.getValue()); } http://git-wip-us.apache.org/repos/asf/syncope/blob/cb57c5ad/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAuditAppender.java ---------------------------------------------------------------------- diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAuditAppender.java b/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAuditAppender.java index 5383a81..0065543 100644 --- a/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAuditAppender.java +++ b/core/logic/src/main/java/org/apache/syncope/core/logic/AbstractAuditAppender.java @@ -18,6 +18,7 @@ */ package org.apache.syncope.core.logic; +import org.apache.syncope.core.logic.audit.AuditAppender; import org.apache.logging.log4j.core.Appender; import org.apache.logging.log4j.core.appender.rewrite.RewriteAppender; import org.apache.logging.log4j.core.appender.rewrite.RewritePolicy; http://git-wip-us.apache.org/repos/asf/syncope/blob/cb57c5ad/core/logic/src/main/java/org/apache/syncope/core/logic/AuditAppender.java ---------------------------------------------------------------------- diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/AuditAppender.java b/core/logic/src/main/java/org/apache/syncope/core/logic/AuditAppender.java deleted file mode 100644 index 93dbfed..0000000 --- a/core/logic/src/main/java/org/apache/syncope/core/logic/AuditAppender.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.syncope.core.logic; - -import java.util.Set; -import org.apache.logging.log4j.core.Appender; -import org.apache.logging.log4j.core.appender.rewrite.RewriteAppender; -import org.apache.logging.log4j.core.appender.rewrite.RewritePolicy; -import org.apache.syncope.common.lib.types.AuditLoggerName; - -/** - * Basic interface to implement to define a custom audit appender - * - * @see org.apache.syncope.core.logic.DefaultRewriteAuditAppender or org.apache.syncope.core.logic.DefaultAuditAppender - */ -public interface AuditAppender { - - void init(); - - Set<AuditLoggerName> getEvents(); - - Appender getTargetAppender(); - - RewritePolicy getRewritePolicy(); - - String getTargetAppenderName(); - - void setDomainName(String name); - - String getDomainName(); - - boolean isRewriteEnabled(); - - RewriteAppender getRewriteAppender(); -} http://git-wip-us.apache.org/repos/asf/syncope/blob/cb57c5ad/core/logic/src/main/java/org/apache/syncope/core/logic/DefaultAuditAppender.java ---------------------------------------------------------------------- diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/DefaultAuditAppender.java b/core/logic/src/main/java/org/apache/syncope/core/logic/DefaultAuditAppender.java deleted file mode 100644 index 1fd9e5e..0000000 --- a/core/logic/src/main/java/org/apache/syncope/core/logic/DefaultAuditAppender.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.syncope.core.logic; - -import java.util.Collections; -import java.util.Set; -import org.apache.logging.log4j.core.appender.rewrite.RewritePolicy; -import org.apache.syncope.common.lib.types.AuditLoggerName; - -/** - * Default (abstract) implementation of custom audit appender. - * It is bound to an empty collection of events, i.e. it does not create any logger. - * This class has to be extended by non-rewrite appenders - * - * @see org.apache.syncope.fit.core.reference.TestFileAuditAppender - */ -public abstract class DefaultAuditAppender extends AbstractAuditAppender { - - @Override - public void init() { - initTargetAppender(); - } - - @Override - public Set<AuditLoggerName> getEvents() { - return Collections.emptySet(); - } - - @Override - public void initRewriteAppender() { - } - - @Override - public RewritePolicy getRewritePolicy() { - return null; - } - -} http://git-wip-us.apache.org/repos/asf/syncope/blob/cb57c5ad/core/logic/src/main/java/org/apache/syncope/core/logic/DefaultRewriteAuditAppender.java ---------------------------------------------------------------------- diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/DefaultRewriteAuditAppender.java b/core/logic/src/main/java/org/apache/syncope/core/logic/DefaultRewriteAuditAppender.java deleted file mode 100644 index 207502e..0000000 --- a/core/logic/src/main/java/org/apache/syncope/core/logic/DefaultRewriteAuditAppender.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.syncope.core.logic; - -import java.util.Collections; -import java.util.Set; -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.core.LoggerContext; -import org.apache.logging.log4j.core.appender.rewrite.RewriteAppender; -import org.apache.logging.log4j.core.appender.rewrite.RewritePolicy; -import org.apache.logging.log4j.core.config.AppenderRef; -import org.apache.syncope.common.lib.types.AuditLoggerName; - -/** - * Default (abstract) implementation of custom rewriting audit appender; it provides rewrite appender definition and - * a default "pass-through" policy. It is bound to an empty collection of events, i.e. it does not create any logger. - * This class has to be extended by rewrite appenders. - * - * @see org.apache.syncope.fit.core.reference.TestFileRewriteAuditAppender - */ -public abstract class DefaultRewriteAuditAppender extends AbstractAuditAppender { - - @Override - public void init() { - initTargetAppender(); - initRewriteAppender(); - } - - @Override - public void initRewriteAppender() { - rewriteAppender = RewriteAppender.createAppender(getTargetAppenderName() + "_rewrite", - "true", - new AppenderRef[] { AppenderRef.createAppenderRef(getTargetAppenderName(), Level.DEBUG, null) }, - ((LoggerContext) LogManager.getContext(false)).getConfiguration(), getRewritePolicy(), null); - } - - @Override - public Set<AuditLoggerName> getEvents() { - return Collections.emptySet(); - } - - @Override - public RewritePolicy getRewritePolicy() { - return PassThroughRewritePolicy.createPolicy(); - } - -} http://git-wip-us.apache.org/repos/asf/syncope/blob/cb57c5ad/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java ---------------------------------------------------------------------- diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java b/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java index 667efc8..5429c24 100644 --- a/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java +++ b/core/logic/src/main/java/org/apache/syncope/core/logic/LoggerLogic.java @@ -53,6 +53,7 @@ import org.apache.syncope.common.lib.types.UnmatchingRule; import org.apache.syncope.common.lib.types.AnyTypeKind; import org.apache.syncope.common.lib.types.AuditElements; import org.apache.syncope.common.lib.types.StandardEntitlement; +import org.apache.syncope.core.logic.audit.AuditAppender; import org.apache.syncope.core.logic.init.LoggerLoader; import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO; import org.apache.syncope.core.persistence.api.dao.LoggerDAO; @@ -62,7 +63,6 @@ import org.apache.syncope.core.persistence.api.entity.EntityFactory; import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource; import org.apache.syncope.core.persistence.api.entity.Logger; import org.apache.syncope.core.persistence.api.entity.task.SchedTask; -import org.apache.syncope.core.provisioning.java.AuditManagerImpl; import org.apache.syncope.core.spring.BeanUtils; import org.apache.syncope.core.provisioning.java.pushpull.PushJobDelegate; import org.apache.syncope.core.provisioning.java.pushpull.PullJobDelegate; @@ -220,41 +220,41 @@ public class LoggerLogic extends AbstractTransactionalLogic<LoggerTO> { syncopeLogger.setLevel(LoggerLevel.fromLevel(level)); syncopeLogger = loggerDAO.save(syncopeLogger); - boolean isAudit = LoggerType.AUDIT.equals(syncopeLogger.getType()); LoggerContext ctx = (LoggerContext) LogManager.getContext(false); - String domainAuditLoggerName = - AuditManagerImpl.getDomainAuditEventLoggerName(AuthContextUtils.getDomain(), syncopeLogger. - getKey()); - LoggerConfig logConf = SyncopeConstants.ROOT_LOGGER.equals(name) - ? ctx.getConfiguration().getLoggerConfig(LogManager.ROOT_LOGGER_NAME) - : isAudit - ? ctx.getConfiguration().getLoggerConfig(domainAuditLoggerName) - : ctx.getConfiguration().getLoggerConfig(name); - - if (isAudit) { + LoggerConfig logConf; + + if (LoggerType.AUDIT.equals(syncopeLogger.getType())) { + String auditLoggerName = AuditLoggerName.getAuditEventLoggerName( + AuthContextUtils.getDomain(), syncopeLogger.getKey()); + + logConf = ctx.getConfiguration().getLoggerConfig(auditLoggerName); + // SYNCOPE-1144 For each custom audit appender class add related appenders to log4j logger - List<AuditAppender> auditAppenders = loggerLoader.auditAppenders(AuthContextUtils.getDomain()); boolean isRootLogConf = LogManager.ROOT_LOGGER_NAME.equals(logConf.getName()); - final String loggerKey = syncopeLogger.getKey(); if (isRootLogConf) { - logConf = new LoggerConfig(domainAuditLoggerName, null, false); + logConf = new LoggerConfig(auditLoggerName, null, false); } - for (AuditAppender auditAppender : auditAppenders) { - + for (AuditAppender auditAppender : loggerLoader.auditAppenders(AuthContextUtils.getDomain())) { if (IterableUtils.matchesAny(auditAppender.getEvents(), new Predicate<AuditLoggerName>() { @Override public boolean evaluate(final AuditLoggerName auditLoggerName) { - return loggerKey.equalsIgnoreCase(auditLoggerName.toLoggerName()); + return name.equalsIgnoreCase(auditLoggerName.toLoggerName()); } })) { + loggerLoader.addAppenderToContext(ctx, auditAppender, logConf); } } if (isRootLogConf) { - ctx.getConfiguration().addLogger(domainAuditLoggerName, logConf); + ctx.getConfiguration().addLogger(auditLoggerName, logConf); } + } else { + logConf = SyncopeConstants.ROOT_LOGGER.equals(name) + ? ctx.getConfiguration().getLoggerConfig(LogManager.ROOT_LOGGER_NAME) + : ctx.getConfiguration().getLoggerConfig(name); } + logConf.setLevel(level); ctx.updateLoggers(); @@ -289,7 +289,6 @@ public class LoggerLogic extends AbstractTransactionalLogic<LoggerTO> { if (expectedType != syncopeLogger.getType()) { throwInvalidLogger(expectedType); } - boolean isAudit = LoggerType.AUDIT.equals(syncopeLogger.getType()); LoggerTO loggerToDelete = new LoggerTO(); BeanUtils.copyProperties(syncopeLogger, loggerToDelete); @@ -299,14 +298,15 @@ public class LoggerLogic extends AbstractTransactionalLogic<LoggerTO> { // set log level to OFF in order to disable configured logger until next reboot LoggerContext ctx = (LoggerContext) LogManager.getContext(false); - String domainAuditLoggerName = - AuditManagerImpl.getDomainAuditEventLoggerName(AuthContextUtils.getDomain(), syncopeLogger. - getKey()); + + String auditLoggerName = AuditLoggerName.getAuditEventLoggerName( + AuthContextUtils.getDomain(), syncopeLogger.getKey()); org.apache.logging.log4j.core.Logger logger = SyncopeConstants.ROOT_LOGGER.equals(name) ? ctx.getLogger(LogManager.ROOT_LOGGER_NAME) - : isAudit - ? ctx.getLogger(domainAuditLoggerName) - : ctx.getLogger(name); + : LoggerType.AUDIT.equals(syncopeLogger.getType()) + ? ctx.getLogger(auditLoggerName) + : ctx.getLogger(name); + logger.setLevel(Level.OFF); ctx.updateLoggers(); http://git-wip-us.apache.org/repos/asf/syncope/blob/cb57c5ad/core/logic/src/main/java/org/apache/syncope/core/logic/PassThroughRewritePolicy.java ---------------------------------------------------------------------- diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/PassThroughRewritePolicy.java b/core/logic/src/main/java/org/apache/syncope/core/logic/PassThroughRewritePolicy.java deleted file mode 100644 index 08c6c4e..0000000 --- a/core/logic/src/main/java/org/apache/syncope/core/logic/PassThroughRewritePolicy.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.apache.syncope.core.logic; - -import org.apache.logging.log4j.core.Core; -import org.apache.logging.log4j.core.LogEvent; -import org.apache.logging.log4j.core.appender.rewrite.RewritePolicy; -import org.apache.logging.log4j.core.config.plugins.Plugin; -import org.apache.logging.log4j.core.config.plugins.PluginFactory; - -@Plugin(name = "PassThroughRewritePolicy", category = Core.CATEGORY_NAME, elementType = "rewritePolicy", - printObject = true) -public class PassThroughRewritePolicy implements RewritePolicy { - - @Override - public LogEvent rewrite(final LogEvent event) { - return event; - } - - @PluginFactory - public static PassThroughRewritePolicy createPolicy() { - return new PassThroughRewritePolicy(); - } - -} http://git-wip-us.apache.org/repos/asf/syncope/blob/cb57c5ad/core/logic/src/main/java/org/apache/syncope/core/logic/audit/AuditAppender.java ---------------------------------------------------------------------- diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/audit/AuditAppender.java b/core/logic/src/main/java/org/apache/syncope/core/logic/audit/AuditAppender.java new file mode 100644 index 0000000..f6a0716 --- /dev/null +++ b/core/logic/src/main/java/org/apache/syncope/core/logic/audit/AuditAppender.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.syncope.core.logic.audit; + +import java.util.Set; +import org.apache.logging.log4j.core.Appender; +import org.apache.logging.log4j.core.appender.rewrite.RewriteAppender; +import org.apache.logging.log4j.core.appender.rewrite.RewritePolicy; +import org.apache.syncope.common.lib.types.AuditLoggerName; + +/** + * Basic interface to implement to define a custom audit appender + * + * @see DefaultAuditAppender + * @see DefaultRewriteAuditAppender + */ +public interface AuditAppender { + + void init(); + + Set<AuditLoggerName> getEvents(); + + Appender getTargetAppender(); + + RewritePolicy getRewritePolicy(); + + String getTargetAppenderName(); + + void setDomainName(String name); + + String getDomainName(); + + boolean isRewriteEnabled(); + + RewriteAppender getRewriteAppender(); +} http://git-wip-us.apache.org/repos/asf/syncope/blob/cb57c5ad/core/logic/src/main/java/org/apache/syncope/core/logic/audit/DefaultAuditAppender.java ---------------------------------------------------------------------- diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/audit/DefaultAuditAppender.java b/core/logic/src/main/java/org/apache/syncope/core/logic/audit/DefaultAuditAppender.java new file mode 100644 index 0000000..0fdd0b5 --- /dev/null +++ b/core/logic/src/main/java/org/apache/syncope/core/logic/audit/DefaultAuditAppender.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.syncope.core.logic.audit; + +import java.util.Collections; +import java.util.Set; +import org.apache.logging.log4j.core.appender.rewrite.RewritePolicy; +import org.apache.syncope.common.lib.types.AuditLoggerName; +import org.apache.syncope.core.logic.AbstractAuditAppender; + +/** + * Default (abstract) implementation of custom audit appender. + * It is bound to an empty collection of events, i.e. it does not create any logger. + * This class shall be extended by non-rewriting appenders; for rewriting, extend + * {@link DefaultRewriteAuditAppender} instead. + */ +public abstract class DefaultAuditAppender extends AbstractAuditAppender { + + @Override + public void init() { + initTargetAppender(); + } + + @Override + public Set<AuditLoggerName> getEvents() { + return Collections.emptySet(); + } + + @Override + public void initRewriteAppender() { + } + + @Override + public RewritePolicy getRewritePolicy() { + return null; + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/cb57c5ad/core/logic/src/main/java/org/apache/syncope/core/logic/audit/DefaultRewriteAuditAppender.java ---------------------------------------------------------------------- diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/audit/DefaultRewriteAuditAppender.java b/core/logic/src/main/java/org/apache/syncope/core/logic/audit/DefaultRewriteAuditAppender.java new file mode 100644 index 0000000..a937cc9 --- /dev/null +++ b/core/logic/src/main/java/org/apache/syncope/core/logic/audit/DefaultRewriteAuditAppender.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.syncope.core.logic.audit; + +import java.util.Collections; +import java.util.Set; +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.core.LoggerContext; +import org.apache.logging.log4j.core.appender.rewrite.RewriteAppender; +import org.apache.logging.log4j.core.appender.rewrite.RewritePolicy; +import org.apache.logging.log4j.core.config.AppenderRef; +import org.apache.syncope.common.lib.types.AuditLoggerName; +import org.apache.syncope.core.logic.AbstractAuditAppender; + +/** + * Default (abstract) implementation of custom rewriting audit appender; it provides rewrite appender definition and + * a default "pass-through" policy. + * It is bound to an empty collection of events, i.e. it does not create any logger. + * This class shall be extended by rewriting appenders; for non-rewriting, extend {@link DefaultAuditAppender} instead. + */ +public abstract class DefaultRewriteAuditAppender extends AbstractAuditAppender { + + @Override + public void init() { + initTargetAppender(); + initRewriteAppender(); + } + + @Override + public void initRewriteAppender() { + rewriteAppender = RewriteAppender.createAppender(getTargetAppenderName() + "_rewrite", + "true", + new AppenderRef[] { AppenderRef.createAppenderRef(getTargetAppenderName(), Level.DEBUG, null) }, + ((LoggerContext) LogManager.getContext(false)).getConfiguration(), getRewritePolicy(), null); + } + + @Override + public Set<AuditLoggerName> getEvents() { + return Collections.emptySet(); + } + + @Override + public RewritePolicy getRewritePolicy() { + return PassThroughAuditRewritePolicy.createPolicy(); + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/cb57c5ad/core/logic/src/main/java/org/apache/syncope/core/logic/audit/PassThroughAuditRewritePolicy.java ---------------------------------------------------------------------- diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/audit/PassThroughAuditRewritePolicy.java b/core/logic/src/main/java/org/apache/syncope/core/logic/audit/PassThroughAuditRewritePolicy.java new file mode 100644 index 0000000..b3ee968 --- /dev/null +++ b/core/logic/src/main/java/org/apache/syncope/core/logic/audit/PassThroughAuditRewritePolicy.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.syncope.core.logic.audit; + +import org.apache.logging.log4j.core.Core; +import org.apache.logging.log4j.core.LogEvent; +import org.apache.logging.log4j.core.appender.rewrite.RewritePolicy; +import org.apache.logging.log4j.core.config.plugins.Plugin; +import org.apache.logging.log4j.core.config.plugins.PluginFactory; + +@Plugin(name = "PassThroughRewritePolicy", + category = Core.CATEGORY_NAME, + elementType = "rewritePolicy", + printObject = true) +public class PassThroughAuditRewritePolicy implements RewritePolicy { + + @Override + public LogEvent rewrite(final LogEvent event) { + return event; + } + + @PluginFactory + public static PassThroughAuditRewritePolicy createPolicy() { + return new PassThroughAuditRewritePolicy(); + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/cb57c5ad/core/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java ---------------------------------------------------------------------- diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java b/core/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java index 902fa4d..1b9bc72 100644 --- a/core/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java +++ b/core/logic/src/main/java/org/apache/syncope/core/logic/init/ClassPathScanImplementationLookup.java @@ -28,7 +28,7 @@ import java.util.Set; import org.apache.syncope.common.lib.policy.AccountRuleConf; import org.apache.syncope.common.lib.policy.PasswordRuleConf; import org.apache.syncope.common.lib.report.ReportletConf; -import org.apache.syncope.core.logic.AuditAppender; +import org.apache.syncope.core.logic.audit.AuditAppender; import org.apache.syncope.core.persistence.api.ImplementationLookup; import org.apache.syncope.core.persistence.api.attrvalue.validation.Validator; import org.apache.syncope.core.persistence.api.dao.AccountRule; http://git-wip-us.apache.org/repos/asf/syncope/blob/cb57c5ad/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerAccessor.java ---------------------------------------------------------------------- diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerAccessor.java b/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerAccessor.java index 675fd94..4f71ae6 100644 --- a/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerAccessor.java +++ b/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerAccessor.java @@ -24,13 +24,13 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.core.LoggerContext; import org.apache.logging.log4j.core.config.LoggerConfig; import org.apache.syncope.common.lib.SyncopeConstants; +import org.apache.syncope.common.lib.types.AuditLoggerName; import org.apache.syncope.common.lib.types.LoggerLevel; import org.apache.syncope.common.lib.types.LoggerType; import org.apache.syncope.core.spring.security.AuthContextUtils; import org.apache.syncope.core.persistence.api.dao.LoggerDAO; import org.apache.syncope.core.persistence.api.entity.EntityFactory; import org.apache.syncope.core.persistence.api.entity.Logger; -import org.apache.syncope.core.provisioning.java.AuditManagerImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; @@ -58,8 +58,8 @@ public class LoggerAccessor { } } for (Logger syncopeLogger : loggerDAO.findAll(LoggerType.AUDIT)) { - syncopeLoggers.put(AuditManagerImpl.getDomainAuditEventLoggerName(AuthContextUtils.getDomain(), - syncopeLogger.getKey()), syncopeLogger); + syncopeLoggers.put(AuditLoggerName.getAuditEventLoggerName( + AuthContextUtils.getDomain(), syncopeLogger.getKey()), syncopeLogger); } /* @@ -73,8 +73,9 @@ public class LoggerAccessor { if (syncopeLoggers.containsKey(loggerName)) { logConf.setLevel(syncopeLoggers.get(loggerName).getLevel().getLevel()); syncopeLoggers.remove(loggerName); - } else if (!loggerName.startsWith(LoggerType.AUDIT.getPrefix()) || !loggerName.startsWith( - AuthContextUtils.getDomain() + "." + LoggerType.AUDIT.getPrefix())) { + } else if (!loggerName.startsWith(LoggerType.AUDIT.getPrefix()) + || !loggerName.startsWith(AuthContextUtils.getDomain() + "." + LoggerType.AUDIT.getPrefix())) { + Logger syncopeLogger = entityFactory.newEntity(Logger.class); syncopeLogger.setKey(loggerName); syncopeLogger.setLevel(LoggerLevel.fromLevel(logConf.getLevel())); @@ -88,9 +89,8 @@ public class LoggerAccessor { * Foreach SyncopeLogger not found in log4j create a new log4j logger with given name and level. */ for (Map.Entry<String, Logger> entry : syncopeLoggers.entrySet()) { - Logger syncopeLogger = entry.getValue(); LoggerConfig logConf = ctx.getConfiguration().getLoggerConfig(entry.getKey()); - logConf.setLevel(syncopeLogger.getLevel().getLevel()); + logConf.setLevel(entry.getValue().getLevel().getLevel()); } ctx.updateLoggers(); http://git-wip-us.apache.org/repos/asf/syncope/blob/cb57c5ad/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java ---------------------------------------------------------------------- diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java b/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java index 4a24d32..e4a4bc5 100644 --- a/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java +++ b/core/logic/src/main/java/org/apache/syncope/core/logic/init/LoggerLoader.java @@ -36,9 +36,8 @@ import org.apache.logging.log4j.core.appender.db.jdbc.JdbcAppender; import org.apache.logging.log4j.core.appender.rewrite.RewriteAppender; import org.apache.logging.log4j.core.config.LoggerConfig; import org.apache.syncope.common.lib.types.AuditLoggerName; -import org.apache.syncope.core.logic.AuditAppender; +import org.apache.syncope.core.logic.audit.AuditAppender; import org.apache.syncope.core.logic.MemoryAppender; -import org.apache.syncope.core.provisioning.java.AuditManagerImpl; import org.apache.syncope.core.spring.security.AuthContextUtils; import org.apache.syncope.core.persistence.api.DomainsHolder; import org.apache.syncope.core.persistence.api.ImplementationLookup; @@ -111,13 +110,28 @@ public class LoggerLoader implements SyncopeLoader { } LoggerConfig logConf = new LoggerConfig( - AuditManagerImpl.getDomainAuditLoggerName(entry.getKey()), null, false); + AuditLoggerName.getAuditLoggerName(entry.getKey()), null, false); logConf.addAppender(appender, Level.DEBUG, null); logConf.setLevel(Level.DEBUG); - ctx.getConfiguration().addLogger(AuditManagerImpl.getDomainAuditLoggerName(entry.getKey()), logConf); + ctx.getConfiguration().addLogger(AuditLoggerName.getAuditLoggerName(entry.getKey()), logConf); // SYNCOPE-1144 For each custom audit appender class add related appenders to log4j logger - configureCustomAppenders(entry.getKey(), ctx); + for (AuditAppender auditAppender : auditAppenders(entry.getKey())) { + for (AuditLoggerName event : auditAppender.getEvents()) { + String domainAuditLoggerName = + AuditLoggerName.getAuditEventLoggerName(entry.getKey(), event.toLoggerName()); + LoggerConfig eventLogConf = ctx.getConfiguration().getLoggerConfig(domainAuditLoggerName); + + if (LogManager.ROOT_LOGGER_NAME.equals(eventLogConf.getName())) { + eventLogConf = new LoggerConfig(domainAuditLoggerName, null, false); + } + addAppenderToContext(ctx, auditAppender, eventLogConf); + eventLogConf.setLevel(Level.DEBUG); + if (LogManager.ROOT_LOGGER_NAME.equals(eventLogConf.getName())) { + ctx.getConfiguration().addLogger(domainAuditLoggerName, eventLogConf); + } + } + } AuthContextUtils.execWithAuthContext(entry.getKey(), new AuthContextUtils.Executable<Void>() { @@ -136,28 +150,7 @@ public class LoggerLoader implements SyncopeLoader { return memoryAppenders; } - public void configureCustomAppenders(final String domainName, final LoggerContext ctx) { - List<AuditAppender> auditAppenders = auditAppenders(domainName); - for (AuditAppender auditAppender : auditAppenders) { - for (AuditLoggerName event : auditAppender.getEvents()) { - String domainAuditLoggerName = - AuditManagerImpl.getDomainAuditEventLoggerName(domainName, event.toLoggerName()); - LoggerConfig eventLogConf = ctx.getConfiguration().getLoggerConfig(domainAuditLoggerName); - boolean isRootLogConf = LogManager.ROOT_LOGGER_NAME.equals(eventLogConf.getName()); - - if (isRootLogConf) { - eventLogConf = new LoggerConfig(domainAuditLoggerName, null, false); - } - addAppenderToContext(ctx, auditAppender, eventLogConf); - eventLogConf.setLevel(Level.DEBUG); - if (isRootLogConf) { - ctx.getConfiguration().addLogger(domainAuditLoggerName, eventLogConf); - } - } - } - } - - public List<AuditAppender> auditAppenders(final String domainName) throws BeansException { + public List<AuditAppender> auditAppenders(final String domain) throws BeansException { List<AuditAppender> auditAppenders = new ArrayList<>(); for (Class<?> clazz : implementationLookup.getAuditAppenderClasses()) { AuditAppender auditAppender; @@ -167,7 +160,7 @@ public class LoggerLoader implements SyncopeLoader { } else { auditAppender = (AuditAppender) ApplicationContextProvider.getBeanFactory(). createBean(clazz, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, true); - auditAppender.setDomainName(domainName); + auditAppender.setDomainName(domain); auditAppender.init(); } auditAppenders.add(auditAppender); @@ -179,6 +172,7 @@ public class LoggerLoader implements SyncopeLoader { final LoggerContext ctx, final AuditAppender auditAppender, final LoggerConfig eventLogConf) { + Appender targetAppender = ctx.getConfiguration().getAppender(auditAppender.getTargetAppenderName()); if (targetAppender == null) { targetAppender = auditAppender.getTargetAppender(); http://git-wip-us.apache.org/repos/asf/syncope/blob/cb57c5ad/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/AuditManagerImpl.java ---------------------------------------------------------------------- diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/AuditManagerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/AuditManagerImpl.java index 760a9fa..6b32cbb 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/AuditManagerImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/AuditManagerImpl.java @@ -23,7 +23,6 @@ import org.apache.syncope.common.lib.types.AuditElements; import org.apache.syncope.common.lib.types.AuditElements.Result; import org.apache.syncope.common.lib.types.AuditLoggerName; import org.apache.syncope.common.lib.types.LoggerLevel; -import org.apache.syncope.common.lib.types.LoggerType; import org.apache.syncope.core.spring.security.AuthContextUtils; import org.apache.syncope.core.provisioning.api.serialization.POJOHelper; import org.apache.syncope.core.persistence.api.dao.LoggerDAO; @@ -41,14 +40,6 @@ public class AuditManagerImpl implements AuditManager { @Autowired private LoggerDAO loggerDAO; - public static String getDomainAuditLoggerName(final String domain) { - return LoggerType.AUDIT.getPrefix() + "." + domain; - } - - public static String getDomainAuditEventLoggerName(final String domain, final String loggerName) { - return domain + "." + loggerName; - } - @Override public boolean auditRequested( final AuditElements.EventCategoryType type, @@ -121,9 +112,10 @@ public class AuditManagerImpl implements AuditManager { org.apache.syncope.core.persistence.api.entity.Logger syncopeLogger = loggerDAO.find(auditEntry.getLogger().toLoggerName()); if (syncopeLogger != null && syncopeLogger.getLevel() == LoggerLevel.DEBUG) { - Logger logger = LoggerFactory.getLogger(getDomainAuditLoggerName(AuthContextUtils.getDomain())); - Logger eventLogger = LoggerFactory.getLogger(getDomainAuditEventLoggerName(AuthContextUtils.getDomain(), - syncopeLogger.getKey())); + Logger logger = LoggerFactory.getLogger( + AuditLoggerName.getAuditLoggerName(AuthContextUtils.getDomain())); + Logger eventLogger = LoggerFactory.getLogger( + AuditLoggerName.getAuditEventLoggerName(AuthContextUtils.getDomain(), syncopeLogger.getKey())); String serializedAuditEntry = POJOHelper.serialize(auditEntry); if (throwable == null) { logger.debug(serializedAuditEntry); http://git-wip-us.apache.org/repos/asf/syncope/blob/cb57c5ad/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/SyslogRewriteAuditAppender.java ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/SyslogRewriteAuditAppender.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/SyslogRewriteAuditAppender.java index 9a192df..0efc767 100644 --- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/SyslogRewriteAuditAppender.java +++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/SyslogRewriteAuditAppender.java @@ -27,7 +27,7 @@ import org.apache.logging.log4j.core.net.Protocol; import org.apache.syncope.common.lib.types.AuditElements; import org.apache.syncope.common.lib.types.AuditLoggerName; import org.apache.syncope.core.logic.ConnectorLogic; -import org.apache.syncope.core.logic.DefaultRewriteAuditAppender; +import org.apache.syncope.core.logic.audit.DefaultRewriteAuditAppender; import org.apache.syncope.core.logic.ResourceLogic; public class SyslogRewriteAuditAppender extends DefaultRewriteAuditAppender { http://git-wip-us.apache.org/repos/asf/syncope/blob/cb57c5ad/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestFileAuditAppender.java ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestFileAuditAppender.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestFileAuditAppender.java index cffc8f7..8942a5c 100644 --- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestFileAuditAppender.java +++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestFileAuditAppender.java @@ -30,7 +30,7 @@ import org.apache.logging.log4j.core.layout.PatternLayout; import org.apache.syncope.common.lib.types.AuditElements; import org.apache.syncope.common.lib.types.AuditLoggerName; import org.apache.syncope.core.logic.ConnectorLogic; -import org.apache.syncope.core.logic.DefaultAuditAppender; +import org.apache.syncope.core.logic.audit.DefaultAuditAppender; import org.apache.syncope.core.logic.ResourceLogic; public class TestFileAuditAppender extends DefaultAuditAppender { http://git-wip-us.apache.org/repos/asf/syncope/blob/cb57c5ad/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestFileRewriteAuditAppender.java ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestFileRewriteAuditAppender.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestFileRewriteAuditAppender.java index 932ce56..83af712 100644 --- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestFileRewriteAuditAppender.java +++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestFileRewriteAuditAppender.java @@ -18,7 +18,6 @@ */ package org.apache.syncope.fit.core.reference; -import java.io.File; import java.util.HashSet; import java.util.Set; import org.apache.commons.lang3.StringUtils; @@ -30,7 +29,7 @@ import org.apache.logging.log4j.core.appender.rewrite.RewritePolicy; import org.apache.logging.log4j.core.layout.PatternLayout; import org.apache.syncope.common.lib.types.AuditElements; import org.apache.syncope.common.lib.types.AuditLoggerName; -import org.apache.syncope.core.logic.DefaultRewriteAuditAppender; +import org.apache.syncope.core.logic.audit.DefaultRewriteAuditAppender; import org.apache.syncope.core.logic.ResourceLogic; public class TestFileRewriteAuditAppender extends DefaultRewriteAuditAppender { @@ -51,20 +50,17 @@ public class TestFileRewriteAuditAppender extends DefaultRewriteAuditAppender { @Override public void initTargetAppender() { LoggerContext ctx = (LoggerContext) LogManager.getContext(false); + // get log file path from existing file appender RollingRandomAccessFileAppender mainFile = (RollingRandomAccessFileAppender) ctx.getConfiguration().getAppender("mainFile"); + String pathPrefix = StringUtils.replace(mainFile.getFileName(), "core.log", StringUtils.EMPTY); - String pathPrefix = mainFile == null - ? System.getProperty("user.dir") + StringUtils.replace("/target/log", "/", File.separator) - + File.separator - : StringUtils.replace(mainFile.getFileName(), "core.log", StringUtils.EMPTY); - - targetAppender = FileAppender.newBuilder() - .withName(getTargetAppenderName()) - .withAppend(true) - .withFileName(pathPrefix + getTargetAppenderName() + ".log") - .withLayout( + targetAppender = FileAppender.newBuilder(). + withName(getTargetAppenderName()). + withAppend(true). + withFileName(pathPrefix + getTargetAppenderName() + ".log"). + withLayout( PatternLayout.newBuilder() .withPattern("%d{HH:mm:ss.SSS} %-5level %logger - %msg%n") .build()) http://git-wip-us.apache.org/repos/asf/syncope/blob/cb57c5ad/fit/core-reference/src/test/java/org/apache/syncope/fit/core/LoggerITCase.java ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/LoggerITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/LoggerITCase.java index 9bc6ed6..0f7253e 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/LoggerITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/LoggerITCase.java @@ -27,6 +27,7 @@ import static org.junit.Assert.fail; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.nio.charset.Charset; import java.text.ParseException; import java.util.List; import java.util.Properties; @@ -59,7 +60,6 @@ import org.apache.syncope.core.logic.ResourceLogic; import org.apache.syncope.core.logic.GroupLogic; import org.apache.syncope.core.logic.UserLogic; import org.apache.syncope.fit.AbstractITCase; -import org.junit.Assert; import org.junit.Test; public class LoggerITCase extends AbstractITCase { @@ -256,45 +256,17 @@ public class LoggerITCase extends AbstractITCase { } @Test - public void issueSYNCOPE708() { - try { - loggerService.read(LoggerType.LOG, "notExists"); - fail("Reading non-existing logger, it should go in exception"); - } catch (final WebServiceException ex) { - fail("Exception is WebServiceException but it should be SyncopeClientException"); - } catch (final SyncopeClientException ex) { - assertEquals(Response.Status.NOT_FOUND, ex.getType().getResponseStatus()); - } - } - - @Test - public void issueSYNCOPE976() { - List<EventCategoryTO> events = loggerService.events(); - assertNotNull(events); - - EventCategoryTO userLogic = IterableUtils.find(events, new Predicate<EventCategoryTO>() { - - @Override - public boolean evaluate(final EventCategoryTO object) { - return "UserLogic".equals(object.getCategory()); - } - }); - assertNotNull(userLogic); - assertEquals(1, IterableUtils.frequency(userLogic.getEvents(), "create")); - } - - @Test - public void testCustomAuditAppender() throws IOException, InterruptedException { + public void customAuditAppender() throws IOException, InterruptedException { InputStream propStream = null; try { Properties props = new Properties(); propStream = getClass().getResourceAsStream("/core-test.properties"); props.load(propStream); - final String auditFilePath = props.getProperty("test.log.dir") + File.separator - + "audit_for_Master_file.log"; - final String auditNoRewriteFilePath = props.getProperty("test.log.dir") + File.separator - + "audit_for_Master_norewrite_file.log"; + String auditFilePath = props.getProperty("test.log.dir") + + File.separator + "audit_for_Master_file.log"; + String auditNoRewriteFilePath = props.getProperty("test.log.dir") + + File.separator + "audit_for_Master_norewrite_file.log"; // 1. Enable audit for resource update -> catched by FileRewriteAuditAppender AuditLoggerName auditLoggerResUpd = new AuditLoggerName( EventCategoryType.LOGIC, @@ -307,6 +279,7 @@ public class LoggerITCase extends AbstractITCase { loggerTOUpd.setKey(auditLoggerResUpd.toLoggerName()); loggerTOUpd.setLevel(LoggerLevel.DEBUG); loggerService.update(LoggerType.AUDIT, loggerTOUpd); + // 2. Enable audit for connector update -> NOT catched by FileRewriteAuditAppender AuditLoggerName auditLoggerConnUpd = new AuditLoggerName( EventCategoryType.LOGIC, @@ -333,21 +306,21 @@ public class LoggerITCase extends AbstractITCase { File auditTempFile = new File(auditFilePath); // check audit_for_Master_file.log, it should contain only a static message - String auditLog = FileUtils.readFileToString(auditTempFile, "UTF-8"); + String auditLog = FileUtils.readFileToString(auditTempFile, Charset.defaultCharset()); - Assert.assertTrue(StringUtils.contains(auditLog, + assertTrue(StringUtils.contains(auditLog, "DEBUG Master.syncope.audit.[LOGIC]:[ResourceLogic]:[]:[update]:[SUCCESS]" + " - This is a static test message")); File auditNoRewriteTempFile = new File(auditNoRewriteFilePath); // check audit_for_Master_file.log, it should contain only a static message - String auditLogNoRewrite = FileUtils.readFileToString(auditNoRewriteTempFile, "UTF-8"); + String auditLogNoRewrite = FileUtils.readFileToString(auditNoRewriteTempFile, Charset.defaultCharset()); - Assert.assertFalse(StringUtils.contains(auditLogNoRewrite, + assertFalse(StringUtils.contains(auditLogNoRewrite, "DEBUG Master.syncope.audit.[LOGIC]:[ResourceLogic]:[]:[update]:[SUCCESS]" + " - This is a static test message")); // clean audit_for_Master_file.log - FileUtils.writeStringToFile(auditTempFile, StringUtils.EMPTY, "UTF-8"); + FileUtils.writeStringToFile(auditTempFile, StringUtils.EMPTY, Charset.defaultCharset()); loggerService.delete(LoggerType.AUDIT, "syncope.audit.[LOGIC]:[ResourceLogic]:[]:[update]:[SUCCESS]"); resource = resourceService.read(RESOURCE_NAME_CSV); @@ -356,11 +329,39 @@ public class LoggerITCase extends AbstractITCase { resourceService.update(resource); // check that nothing has been written to audit_for_Master_file.log - assertTrue(StringUtils.isEmpty(FileUtils.readFileToString(auditTempFile, "UTF-8"))); + assertTrue(StringUtils.isEmpty(FileUtils.readFileToString(auditTempFile, Charset.defaultCharset()))); } catch (IOException e) { fail("Unable to read/write log files" + e.getMessage()); } finally { IOUtils.closeQuietly(propStream); } } + + @Test + public void issueSYNCOPE708() { + try { + loggerService.read(LoggerType.LOG, "notExists"); + fail("Reading non-existing logger, it should go in exception"); + } catch (final WebServiceException ex) { + fail("Exception is WebServiceException but it should be SyncopeClientException"); + } catch (final SyncopeClientException ex) { + assertEquals(Response.Status.NOT_FOUND, ex.getType().getResponseStatus()); + } + } + + @Test + public void issueSYNCOPE976() { + List<EventCategoryTO> events = loggerService.events(); + assertNotNull(events); + + EventCategoryTO userLogic = IterableUtils.find(events, new Predicate<EventCategoryTO>() { + + @Override + public boolean evaluate(final EventCategoryTO object) { + return "UserLogic".equals(object.getCategory()); + } + }); + assertNotNull(userLogic); + assertEquals(1, IterableUtils.frequency(userLogic.getEvents(), "create")); + } } http://git-wip-us.apache.org/repos/asf/syncope/blob/cb57c5ad/src/main/asciidoc/reference-guide/concepts/audit.adoc ---------------------------------------------------------------------- diff --git a/src/main/asciidoc/reference-guide/concepts/audit.adoc b/src/main/asciidoc/reference-guide/concepts/audit.adoc index 78c38d3..d774594 100644 --- a/src/main/asciidoc/reference-guide/concepts/audit.adoc +++ b/src/main/asciidoc/reference-guide/concepts/audit.adoc @@ -19,8 +19,8 @@ === Audit The audit feature allows to capture <<audit-events,events>> occurring within the <<core>> and to log relevant information -about them. By default events are logged as entries into the `SYNCOPEAUDIT` table of the internal storage, -but can also be logged on some additional Log4j2 appenders defined through simple customization mechanisms. +about them. + +By default, events are logged as entries into the `SYNCOPEAUDIT` table of the internal storage. Once events are reported, they can be used as input for external tools. @@ -34,47 +34,48 @@ An example of how audit entries can be extracted for reporting is shown by the < The information provided for <<notification-events,notification events>> is also valid for audit events, including examples - except for the admin console <<console-configuration-audit,tooling>>, which is naturally distinct. -==== Audit Customization +==== Audit Appenders -As mentioned above, events are, basically, logged in a database table, but this behavior can be extended through -`AuditAppender` interface implementation which allows an user to define additional logging supports that we address -as appenders. +In addition to insertions into the `SYNCOPEAUDIT` table, events are also available for custom handling via Audit +Appenders, based on https://logging.apache.org/log4j/2.x/manual/appenders.html[Apache Log4j 2 Appenders^]. + +This allows to empower the available implementations or to write new ones in order to route audit messages, with optional +transformation (rewrite), to files, queues, sockets, syslog, etc. -Appender is a Log4j entity that allows to write whatever log message on different destinations (file, queues, syslog, -other appenders, etc.). Moreover it provides the ability to edit (rewrite) the message, that is flowing through appenders, -in order to customize information. -Audit customization relies on Log4j appenders. To implement a custom audit appender an user just needs to extend to basic -classes: +Custom implementations must follow the +ifeval::["{snapshotOrRelease}" == "release"] +https://github.com/apache/syncope/blob/syncope-{docVersion}/core/logic/src/main/java/org/apache/syncope/core/logic/audit/AuditAppender.java[AuditAppender^] +endif::[] +ifeval::["{snapshotOrRelease}" == "snapshot"] +https://github.com/apache/syncope/blob/2_0_X/core/logic/src/main/java/org/apache/syncope/core/logic/audit/AuditAppender.java[AuditAppender^] +endif::[] +interface. -. DefaultAuditAppender -. DefaultRewriteAuditAppender +Some convenience implementations are provided, meant to serve as reference - see table below. -The first is intended to add custom appender without any rewrtining of the message, the second allows message rewriting. +[cols="1,2"] +|=== -What is needed to implement a well formed appender: - -. Events: a set of events to which the appender is bound. Appender will log only if one of those events occurs. -. Target Appender: the Log4j appender that writes message somewhere. See - https://github.com/andrea-patricelli/syncope/blob/2_0_X/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestFileRewriteAuditAppender.java[TestFileRewriteAuditAppender^] or - https://github.com/andrea-patricelli/syncope/blob/2_0_X/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestFileAuditAppender.java[TestFileAuditAppender^]. -. Rewrite policy (if needed): in case of rewrite enabled a rewrite policy should be defined, by implementing Log4j - `RewritePolicy` interface. Some examples are - https://github.com/andrea-patricelli/syncope/blob/2_0_X/core/logic/src/main/java/org/apache/syncope/core/logic/PassThroughRewritePolicy.java[PassThroughRewritePolicy^] - and https://github.com/andrea-patricelli/syncope/blob/2_0_X/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestRewritePolicy.java[TestRewritePolicy^]. - If no rewrite policy is specified `PassThroughRewritePolicy` will be used. +| +ifeval::["{snapshotOrRelease}" == "release"] +https://github.com/apache/syncope/blob/syncope-{docVersion}/core/logic/src/main/java/org/apache/syncope/core/logic/audit/DefaultAuditAppender.java[DefaultAuditAppender^] +endif::[] +ifeval::["{snapshotOrRelease}" == "snapshot"] +https://github.com/apache/syncope/blob/2_0_X/core/logic/src/main/java/org/apache/syncope/core/logic/audit/DefaultAuditAppender.java[DefaultAuditAppender^] +endif::[] +| This requires to specify (a) a set of events to which the appender is bound (log only if one of such events occurs) +and (b) a target appender, e.g. one of https://logging.apache.org/log4j/2.x/manual/appenders.html[Apache Log4j 2 Appenders^] +or a custom implementation. -[TIP] -==== -Be careful while assigning names to the appenders. The name of the target appender should be unique and should depend on -the domain. -A best practice is to assign different names to the appenders in order to avoid names collisions and strange behavior of -the logging framework. -==== - -===== How custom appenders work +| +ifeval::["{snapshotOrRelease}" == "release"] +https://github.com/apache/syncope/blob/syncope-{docVersion}/core/logic/src/main/java/org/apache/syncope/core/logic/audit/DefaultRewriteAuditAppender.java[DefaultRewriteAuditAppender^] +endif::[] +ifeval::["{snapshotOrRelease}" == "snapshot"] +https://github.com/apache/syncope/blob/2_0_X/core/logic/src/main/java/org/apache/syncope/core/logic/audit/DefaultRewriteAuditAppender.java[DefaultRewriteAuditAppender^] +endif::[] +| In addition, this requires to provide a +https://logging.apache.org/log4j/2.x/log4j-core/apidocs/org/apache/logging/log4j/core/appender/rewrite/RewritePolicy.html[RewritePolicy^] +implementation, which allows to rewrite the original audit message into something more suitable to the target +destination. -An appender is bound to specific events. While enabling audit on some event, if that event is "catched" also by the custom -appender, it automatically activates. Once the audit is enabled the same audit message will be logged by the -default audit appender and all the extensions bound to those events. While disabling audit all audit extensions are -disabled. -To enable an audit extension an user just needs to implement his custom `AuditAppender` in the sources, build application and deploy. \ No newline at end of file +|=== http://git-wip-us.apache.org/repos/asf/syncope/blob/cb57c5ad/src/main/asciidoc/reference-guide/workingwithapachesyncope/customization.adoc ---------------------------------------------------------------------- diff --git a/src/main/asciidoc/reference-guide/workingwithapachesyncope/customization.adoc b/src/main/asciidoc/reference-guide/workingwithapachesyncope/customization.adoc index c166583..5a115e4 100644 --- a/src/main/asciidoc/reference-guide/workingwithapachesyncope/customization.adoc +++ b/src/main/asciidoc/reference-guide/workingwithapachesyncope/customization.adoc @@ -193,6 +193,7 @@ Besides replacing existing classes as explained <<override-behavior,above>>, new * <<provisioning-managers,provisioning managers>> * <<notifications,notification recipient providers>> * <<jwtssoprovider,JWT SSO providers>> +* <<audit-appenders, audit appenders>> [[new-rest-endpoints]] [TIP] @@ -691,9 +692,3 @@ Moreover, `defaultValues` do not overwrite any existing value. For example, the http://www.chorevolution.eu/[CHOReVOLUTION^] IdM - based on Apache Syncope - provides https://gitlab.ow2.org/chorevolution/syncope/tree/master/ext/choreography[an extension^] for managing via the <<core>> and visualizing via the <<admin-console-component>> the running choreography instances. - -[[audit-customization]] -==== Audit Extensions - -<<audit>> by default, if enabled, logs on a specific database table, though this functionality could be extended to log -also on different supports (file, queue, syslog, etc.).
