You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2015/08/02 07:45:28 UTC
[14/15] syncope git commit: [SYNCOPE-652] Still several things to
refine, but it starts taking shape
http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/logic/src/main/java/org/apache/syncope/core/logic/audit/AuditConnectionFactory.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/audit/AuditConnectionFactory.java b/core/logic/src/main/java/org/apache/syncope/core/logic/audit/AuditConnectionFactory.java
deleted file mode 100644
index b35c42d..0000000
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/audit/AuditConnectionFactory.java
+++ /dev/null
@@ -1,159 +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.audit;
-
-import java.io.InputStream;
-import java.sql.Connection;
-import java.util.Properties;
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.rmi.PortableRemoteObject;
-import javax.sql.DataSource;
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathExpression;
-import javax.xml.xpath.XPathFactory;
-import org.apache.commons.dbcp2.BasicDataSource;
-import org.apache.commons.io.IOUtils;
-import org.springframework.core.io.ClassPathResource;
-import org.springframework.core.io.FileSystemResource;
-import org.springframework.core.io.Resource;
-import org.springframework.core.io.support.PropertiesLoaderUtils;
-import org.springframework.jdbc.datasource.DataSourceUtils;
-import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
-import org.springframework.jdbc.datasource.init.ScriptUtils;
-import org.w3c.dom.Document;
-import org.w3c.dom.bootstrap.DOMImplementationRegistry;
-import org.w3c.dom.ls.DOMImplementationLS;
-import org.w3c.dom.ls.LSInput;
-import org.w3c.dom.ls.LSParser;
-
-/**
- * LOG4J SQL connection factory that first attempts to obtain a {@link javax.sql.DataSource} from the JNDI name
- * configured in Spring or, when not found, builds a new {@link javax.sql.DataSource DataSource} via Commons DBCP; if
- * any datasource if found, the SQL init script is used to populate the database.
- */
-public final class AuditConnectionFactory {
-
- private static DataSource DATASOURCE;
-
- private static final String PERSISTENCE_CONTEXT = "/persistenceContext.xml";
-
- static {
- // 1. Attempts to lookup for configured JNDI datasource (if present and available)
- InputStream springConf = AuditConnectionFactory.class.getResourceAsStream(PERSISTENCE_CONTEXT);
- String primary = null;
- String fallback = null;
- try {
- DOMImplementationRegistry reg = DOMImplementationRegistry.newInstance();
- DOMImplementationLS impl = (DOMImplementationLS) reg.getDOMImplementation("LS");
- LSParser parser = impl.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, null);
- LSInput lsinput = impl.createLSInput();
- lsinput.setByteStream(springConf);
- Document source = parser.parse(lsinput);
-
- XPathFactory xPathfactory = XPathFactory.newInstance();
- XPath xpath = xPathfactory.newXPath();
-
- XPathExpression expr = xpath.compile("//*[local-name()='bean' and @id='persistenceProperties']/"
- + "child::*[local-name()='property' and @name='primary']/@value");
- primary = (String) expr.evaluate(source, XPathConstants.STRING);
- expr = xpath.compile("//*[local-name()='bean' and @id='persistenceProperties']/"
- + "child::*[local-name()='property' and @name='fallback']/@value");
- fallback = (String) expr.evaluate(source, XPathConstants.STRING);
-
- expr = xpath.compile("//*[local-name()='property' and @name='jndiName']/@value");
- String jndiName = (String) expr.evaluate(source, XPathConstants.STRING);
-
- Context ctx = new InitialContext();
- Object obj = ctx.lookup(jndiName);
-
- DATASOURCE = (DataSource) PortableRemoteObject.narrow(obj, DataSource.class);
- } catch (Exception e) {
- // ignore
- } finally {
- IOUtils.closeQuietly(springConf);
- }
-
- // 2. Creates Commons DBCP datasource
- String initSQLScript = null;
- try {
- Resource persistenceProperties = null;
- if (primary != null) {
- if (primary.startsWith("file:")) {
- persistenceProperties = new FileSystemResource(primary.substring(5));
- }
- if (primary.startsWith("classpath:")) {
- persistenceProperties = new ClassPathResource(primary.substring(10));
- }
- }
- if ((persistenceProperties == null || !persistenceProperties.exists()) && fallback != null) {
- if (fallback.startsWith("file:")) {
- persistenceProperties = new FileSystemResource(fallback.substring(5));
- }
- if (fallback.startsWith("classpath:")) {
- persistenceProperties = new ClassPathResource(fallback.substring(10));
- }
- }
- Properties persistence = PropertiesLoaderUtils.loadProperties(persistenceProperties);
-
- initSQLScript = persistence.getProperty("audit.sql");
-
- if (DATASOURCE == null) {
- BasicDataSource bds = new BasicDataSource();
- bds.setDriverClassName(persistence.getProperty("jpa.driverClassName"));
- bds.setUrl(persistence.getProperty("jpa.url"));
- bds.setUsername(persistence.getProperty("jpa.username"));
- bds.setPassword(persistence.getProperty("jpa.password"));
-
- bds.setLogAbandoned(true);
- bds.setRemoveAbandonedOnBorrow(true);
- bds.setRemoveAbandonedOnMaintenance(true);
-
- DATASOURCE = bds;
- }
- } catch (Exception e) {
- throw new IllegalStateException("Audit datasource configuration failed", e);
- }
-
- // 3. Initializes the chosen datasource
- ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
- populator.setScripts(new Resource[] { new ClassPathResource("/audit/" + initSQLScript) });
- // forces no statement separation
- populator.setSeparator(ScriptUtils.EOF_STATEMENT_SEPARATOR);
- Connection conn = DataSourceUtils.getConnection(DATASOURCE);
- try {
- populator.populate(conn);
- } finally {
- DataSourceUtils.releaseConnection(conn, DATASOURCE);
- }
- }
-
- public static Connection getConnection() {
- if (DATASOURCE != null) {
- return DataSourceUtils.getConnection(DATASOURCE);
- }
-
- throw new IllegalStateException("Audit dataSource init failed: check logs");
- }
-
- private AuditConnectionFactory() {
- // empty constructor for static utility class
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/logic/src/main/java/org/apache/syncope/core/logic/init/ImplementationClassNamesLoader.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/init/ImplementationClassNamesLoader.java b/core/logic/src/main/java/org/apache/syncope/core/logic/init/ImplementationClassNamesLoader.java
index b22a54d..2bcd78f 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/init/ImplementationClassNamesLoader.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/init/ImplementationClassNamesLoader.java
@@ -25,9 +25,6 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.core.provisioning.api.job.PushJob;
-import org.apache.syncope.core.provisioning.api.job.SyncJob;
-import org.apache.syncope.core.provisioning.api.job.TaskJob;
import org.apache.syncope.core.provisioning.api.propagation.PropagationActions;
import org.apache.syncope.core.provisioning.api.sync.PushActions;
import org.apache.syncope.core.provisioning.api.sync.SyncActions;
@@ -35,6 +32,9 @@ import org.apache.syncope.core.provisioning.api.sync.SyncCorrelationRule;
import org.apache.syncope.core.logic.report.Reportlet;
import org.apache.syncope.core.persistence.api.SyncopeLoader;
import org.apache.syncope.core.persistence.api.attrvalue.validation.Validator;
+import org.apache.syncope.core.provisioning.api.job.SchedTaskJobDelegate;
+import org.apache.syncope.core.provisioning.java.sync.PushJobDelegate;
+import org.apache.syncope.core.provisioning.java.sync.SyncJobDelegate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.BeanDefinition;
@@ -52,7 +52,7 @@ public class ImplementationClassNamesLoader implements SyncopeLoader {
public enum Type {
REPORTLET,
- TASKJOB,
+ TASKJOBDELEGATE,
PROPAGATION_ACTIONS,
SYNC_ACTIONS,
PUSH_ACTIONS,
@@ -83,7 +83,7 @@ public class ImplementationClassNamesLoader implements SyncopeLoader {
ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
scanner.addIncludeFilter(new AssignableTypeFilter(Reportlet.class));
- scanner.addIncludeFilter(new AssignableTypeFilter(TaskJob.class));
+ scanner.addIncludeFilter(new AssignableTypeFilter(SchedTaskJobDelegate.class));
scanner.addIncludeFilter(new AssignableTypeFilter(SyncActions.class));
scanner.addIncludeFilter(new AssignableTypeFilter(PushActions.class));
scanner.addIncludeFilter(new AssignableTypeFilter(SyncCorrelationRule.class));
@@ -102,11 +102,11 @@ public class ImplementationClassNamesLoader implements SyncopeLoader {
classNames.get(Type.REPORTLET).add(clazz.getName());
}
- if (TaskJob.class.isAssignableFrom(clazz) && !isAbsractClazz
- && !SyncJob.class.isAssignableFrom(clazz)
- && !PushJob.class.isAssignableFrom(clazz)) {
+ if (SchedTaskJobDelegate.class.isAssignableFrom(clazz) && !isAbsractClazz
+ && !SyncJobDelegate.class.isAssignableFrom(clazz)
+ && !PushJobDelegate.class.isAssignableFrom(clazz)) {
- classNames.get(Type.TASKJOB).add(bd.getBeanClassName());
+ classNames.get(Type.TASKJOBDELEGATE).add(bd.getBeanClassName());
}
if (SyncActions.class.isAssignableFrom(clazz) && !isAbsractClazz) {
http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/logic/src/main/java/org/apache/syncope/core/logic/init/JobInstanceLoaderImpl.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/init/JobInstanceLoaderImpl.java b/core/logic/src/main/java/org/apache/syncope/core/logic/init/JobInstanceLoaderImpl.java
index 6a8289a..3e7e90f 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/init/JobInstanceLoaderImpl.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/init/JobInstanceLoaderImpl.java
@@ -19,11 +19,13 @@
package org.apache.syncope.core.logic.init;
import java.text.ParseException;
-import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
-import java.util.List;
+import java.util.Map;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.types.TaskType;
import org.apache.syncope.core.persistence.api.dao.ConfDAO;
import org.apache.syncope.core.persistence.api.dao.NotFoundException;
@@ -37,17 +39,17 @@ import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
import org.apache.syncope.core.persistence.api.entity.task.Task;
import org.apache.syncope.core.provisioning.api.job.JobInstanceLoader;
import org.apache.syncope.core.provisioning.api.job.JobNamer;
-import org.apache.syncope.core.provisioning.api.job.SyncJob;
-import org.apache.syncope.core.provisioning.api.job.TaskJob;
-import org.apache.syncope.core.provisioning.api.sync.SyncActions;
import org.apache.syncope.core.logic.notification.NotificationJob;
import org.apache.syncope.core.logic.report.ReportJob;
+import org.apache.syncope.core.misc.security.AuthContextUtils;
import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.SyncopeLoader;
-import org.apache.syncope.core.provisioning.api.job.PushJob;
-import org.apache.syncope.core.provisioning.java.sync.PushJobImpl;
-import org.apache.syncope.core.provisioning.java.sync.SyncJobImpl;
+import org.apache.syncope.core.persistence.api.DomainsHolder;
+import org.apache.syncope.core.provisioning.java.job.TaskJob;
+import org.apache.syncope.core.provisioning.java.sync.PushJobDelegate;
+import org.apache.syncope.core.provisioning.java.sync.SyncJobDelegate;
import org.quartz.Job;
+import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobKey;
import org.quartz.Scheduler;
@@ -70,6 +72,9 @@ public class JobInstanceLoaderImpl implements JobInstanceLoader, SyncopeLoader {
private static final Logger LOG = LoggerFactory.getLogger(JobInstanceLoader.class);
@Autowired
+ private DomainsHolder domainsHolder;
+
+ @Autowired
private SchedulerFactoryBean scheduler;
@Autowired
@@ -81,7 +86,8 @@ public class JobInstanceLoaderImpl implements JobInstanceLoader, SyncopeLoader {
@Autowired
private ConfDAO confDAO;
- private void registerJob(final String jobName, final Job jobInstance, final String cronExpression)
+ private void registerJob(
+ final String jobName, final Job jobInstance, final String cronExpression, final Map<String, Object> jobMap)
throws SchedulerException, ParseException {
synchronized (scheduler.getScheduler()) {
@@ -112,6 +118,7 @@ public class JobInstanceLoaderImpl implements JobInstanceLoader, SyncopeLoader {
jobDetail.setName(jobName);
jobDetail.setGroup(Scheduler.DEFAULT_GROUP);
jobDetail.setJobClass(jobInstance.getClass());
+ jobDetail.setJobDataMap(new JobDataMap(jobMap));
// 3. Trigger
if (cronExpression == null) {
@@ -127,12 +134,13 @@ public class JobInstanceLoaderImpl implements JobInstanceLoader, SyncopeLoader {
}
}
- private Job createSpringBean(final Class<?> jobClass) {
- Job jobInstance = null;
+ @SuppressWarnings("unchecked")
+ private <T> T createSpringBean(final Class<T> jobClass) {
+ T jobInstance = null;
for (int i = 0; i < 5 && jobInstance == null; i++) {
LOG.debug("{} attempt to create Spring bean for {}", i, jobClass);
try {
- jobInstance = (Job) ApplicationContextProvider.getBeanFactory().
+ jobInstance = (T) ApplicationContextProvider.getBeanFactory().
createBean(jobClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false);
LOG.debug("{} attempt to create Spring bean for {} succeeded", i, jobClass);
} catch (BeanCreationException e) {
@@ -151,75 +159,43 @@ public class JobInstanceLoaderImpl implements JobInstanceLoader, SyncopeLoader {
return jobInstance;
}
- @SuppressWarnings("unchecked")
@Override
- public void registerJob(final Task task, final String jobClassName, final String cronExpression)
- throws ClassNotFoundException, SchedulerException, ParseException {
-
- Class<?> jobClass = Class.forName(jobClassName);
- if (SyncJob.class.equals(jobClass)) {
- jobClass = SyncJobImpl.class;
- } else if (PushJob.class.equals(jobClass)) {
- jobClass = PushJobImpl.class;
- }
-
- Job jobInstance = createSpringBean(jobClass);
- if (jobInstance instanceof TaskJob) {
- ((TaskJob) jobInstance).setTaskId(task.getKey());
- }
-
- // In case of synchronization job/task retrieve and set synchronization actions:
- // actions cannot be changed at runtime but connector and synchronization policies (reloaded at execution time).
- if (jobInstance instanceof SyncJob && task instanceof SyncTask) {
- final List<SyncActions> actions = new ArrayList<>();
- for (String className : ((SyncTask) task).getActionsClassNames()) {
- try {
- Class<?> actionsClass = Class.forName(className);
-
- SyncActions syncActions = (SyncActions) ApplicationContextProvider.getBeanFactory().
- createBean(actionsClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, true);
- actions.add(syncActions);
- } catch (Exception e) {
- LOG.info("Class '{}' not found", className, e);
- }
- }
+ public Map<String, Object> registerJob(final SchedTask task, final long interruptMaxRetries)
+ throws SchedulerException, ParseException {
- ((SyncJob) jobInstance).setActions(actions);
- }
+ TaskJob job = createSpringBean(TaskJob.class);
+ job.setTaskKey(task.getKey());
- registerJob(JobNamer.getJobName(task), jobInstance, cronExpression);
- }
+ String jobDelegateClassName = task instanceof SyncTask
+ ? SyncJobDelegate.class.getName()
+ : task instanceof PushTask
+ ? PushJobDelegate.class.getName()
+ : task.getJobDelegateClassName();
- @Transactional(readOnly = true)
- @Override
- public void registerTaskJob(final Long taskKey)
- throws ClassNotFoundException, SchedulerException, ParseException {
+ Map<String, Object> jobMap = new HashMap<>();
+ jobMap.put(JobInstanceLoader.DOMAIN, AuthContextUtils.getDomain());
+ jobMap.put(TaskJob.DELEGATE_CLASS_KEY, jobDelegateClassName);
+ jobMap.put(TaskJob.INTERRUPT_MAX_RETRIES_KEY, interruptMaxRetries);
- SchedTask task = taskDAO.find(taskKey);
- if (task == null) {
- throw new NotFoundException("Task " + taskKey);
- } else {
- registerJob(task, task.getJobClassName(), task.getCronExpression());
- }
+ registerJob(JobNamer.getJobName(task), job, task.getCronExpression(), jobMap);
+ return jobMap;
}
@Override
public void registerJob(final Report report) throws SchedulerException, ParseException {
- Job jobInstance = createSpringBean(ReportJob.class);
- ((ReportJob) jobInstance).setReportKey(report.getKey());
+ ReportJob job = createSpringBean(ReportJob.class);
+ job.setReportKey(report.getKey());
+
+ Map<String, Object> jobMap = new HashMap<>();
+ jobMap.put(JobInstanceLoader.DOMAIN, AuthContextUtils.getDomain());
- registerJob(JobNamer.getJobName(report), jobInstance, report.getCronExpression());
+ registerJob(JobNamer.getJobName(report), job, report.getCronExpression(), jobMap);
}
- @Transactional(readOnly = true)
- @Override
- public void registerReportJob(final Long reportKey) throws SchedulerException, ParseException {
- Report report = reportDAO.find(reportKey);
- if (report == null) {
- throw new NotFoundException("Report " + reportKey);
- } else {
- registerJob(report);
- }
+ private void registerNotificationJob(final String cronExpression) throws SchedulerException, ParseException {
+ NotificationJob job = createSpringBean(NotificationJob.class);
+
+ registerJob("taskNotificationJob", job, cronExpression, Collections.<String, Object>emptyMap());
}
private void unregisterJob(final String jobName) {
@@ -253,41 +229,62 @@ public class JobInstanceLoaderImpl implements JobInstanceLoader, SyncopeLoader {
@Transactional
@Override
public void load() {
- // 1. jobs for SchedTasks
- Set<SchedTask> tasks = new HashSet<>(taskDAO.<SchedTask>findAll(TaskType.SCHEDULED));
- tasks.addAll(taskDAO.<SyncTask>findAll(TaskType.SYNCHRONIZATION));
- tasks.addAll(taskDAO.<PushTask>findAll(TaskType.PUSH));
- for (SchedTask task : tasks) {
+ AuthContextUtils.setFakeAuth(SyncopeConstants.MASTER_DOMAIN);
+ String notificationJobCronExpression = StringUtils.EMPTY;
+ long interruptMaxRetries = 1;
+ try {
+ CPlainAttr notificationJobCronExp =
+ confDAO.find("notificationjob.cronExpression", NotificationJob.DEFAULT_CRON_EXP);
+ if (!notificationJobCronExp.getValuesAsStrings().isEmpty()) {
+ notificationJobCronExpression = notificationJobCronExp.getValuesAsStrings().get(0);
+ }
+
+ interruptMaxRetries = confDAO.find("tasks.interruptMaxRetries", "1").getValues().get(0).getLongValue();
+ } finally {
+ AuthContextUtils.clearFakeAuth();
+ }
+
+ for (String domain : domainsHolder.getDomains().keySet()) {
+ AuthContextUtils.setFakeAuth(domain);
+
try {
- registerJob(task, task.getJobClassName(), task.getCronExpression());
- } catch (Exception e) {
- LOG.error("While loading job instance for task " + task.getKey(), e);
+ // 1. jobs for SchedTasks
+ Set<SchedTask> tasks = new HashSet<>(taskDAO.<SchedTask>findAll(TaskType.SCHEDULED));
+ tasks.addAll(taskDAO.<SyncTask>findAll(TaskType.SYNCHRONIZATION));
+ tasks.addAll(taskDAO.<PushTask>findAll(TaskType.PUSH));
+ for (SchedTask task : tasks) {
+ try {
+ registerJob(task, interruptMaxRetries);
+ } catch (Exception e) {
+ LOG.error("While loading job instance for task " + task.getKey(), e);
+ }
+ }
+
+ // 2. ReportJobs
+ for (Report report : reportDAO.findAll()) {
+ try {
+ registerJob(report);
+ } catch (Exception e) {
+ LOG.error("While loading job instance for report " + report.getName(), e);
+ }
+ }
+ } finally {
+ AuthContextUtils.clearFakeAuth();
}
}
- // 2. NotificationJob
- CPlainAttr notificationJobCronExp =
- confDAO.find("notificationjob.cronExpression", NotificationJob.DEFAULT_CRON_EXP);
- if (StringUtils.isBlank(notificationJobCronExp.getValuesAsStrings().get(0))) {
+ // 3. NotificationJob
+ if (StringUtils.isBlank(notificationJobCronExpression)) {
LOG.debug("Empty value provided for NotificationJob's cron, not registering anything on Quartz");
} else {
LOG.debug("NotificationJob's cron expression: {} - registering Quartz job and trigger",
- notificationJobCronExp);
+ notificationJobCronExpression);
try {
- registerJob(null, NotificationJob.class.getName(), notificationJobCronExp.getValuesAsStrings().get(0));
+ registerNotificationJob(notificationJobCronExpression);
} catch (Exception e) {
LOG.error("While loading NotificationJob instance", e);
}
}
-
- // 3. ReportJobs
- for (Report report : reportDAO.findAll()) {
- try {
- registerJob(report);
- } catch (Exception e) {
- LOG.error("While loading job instance for report " + report.getName(), e);
- }
- }
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/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 447a92f..e86b46a 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
@@ -18,19 +18,30 @@
*/
package org.apache.syncope.core.logic.init;
+import java.sql.Connection;
+import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
+import javax.sql.DataSource;
+import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.appender.db.jdbc.ColumnConfig;
+import org.apache.logging.log4j.core.appender.db.jdbc.ConnectionSource;
+import org.apache.logging.log4j.core.appender.db.jdbc.JdbcAppender;
import org.apache.logging.log4j.core.config.LoggerConfig;
import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.types.LoggerLevel;
import org.apache.syncope.common.lib.types.LoggerType;
+import org.apache.syncope.core.misc.AuditManager;
+import org.apache.syncope.core.persistence.api.DomainsHolder;
import org.apache.syncope.core.persistence.api.SyncopeLoader;
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.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@@ -38,6 +49,9 @@ import org.springframework.transaction.annotation.Transactional;
public class LoggerLoader implements SyncopeLoader {
@Autowired
+ private DomainsHolder domainsHolder;
+
+ @Autowired
private LoggerDAO loggerDAO;
@Autowired
@@ -51,6 +65,39 @@ public class LoggerLoader implements SyncopeLoader {
@Transactional
@Override
public void load() {
+ LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
+
+ // 1. Audit table and DataSource for each configured domain
+ ColumnConfig[] columns = {
+ ColumnConfig.createColumnConfig(ctx.getConfiguration(), "EVENT_DATE", null, null, "true", null, null),
+ ColumnConfig.createColumnConfig(ctx.getConfiguration(), "LOGGER_LEVEL", "%level", null, null, null, null),
+ ColumnConfig.createColumnConfig(ctx.getConfiguration(), "LOGGER", "%logger", null, null, null, null),
+ ColumnConfig.createColumnConfig(ctx.getConfiguration(), "MESSAGE", "%message", null, null, null, null),
+ ColumnConfig.createColumnConfig(ctx.getConfiguration(), "THROWABLE", "%ex{full}", null, null, null, null)
+ };
+ for (Map.Entry<String, DataSource> entry : domainsHolder.getDomains().entrySet()) {
+ Appender appender = ctx.getConfiguration().getAppender("audit_for_" + entry.getKey());
+ if (appender == null) {
+ appender = JdbcAppender.createAppender(
+ "audit_for_" + entry.getKey(),
+ "false",
+ null,
+ new DataSourceConnectionSource(entry.getValue()),
+ "0",
+ "SYNCOPEAUDIT",
+ columns);
+ appender.start();
+ ctx.getConfiguration().addAppender(appender);
+ }
+
+ LoggerConfig logConf = new LoggerConfig(
+ AuditManager.getDomainAuditLoggerName(entry.getKey()), null, false);
+ logConf.addAppender(appender, Level.DEBUG, null);
+ ctx.getConfiguration().addLogger(AuditManager.getDomainAuditLoggerName(entry.getKey()), logConf);
+ }
+ ctx.updateLoggers();
+
+ // 2. Aligning log4j conf with database content
Map<String, Logger> syncopeLoggers = new HashMap<>();
for (Logger syncopeLogger : loggerDAO.findAll(LoggerType.LOG)) {
syncopeLoggers.put(syncopeLogger.getKey(), syncopeLogger);
@@ -60,8 +107,6 @@ public class LoggerLoader implements SyncopeLoader {
syncopeLoggers.put(syncopeLogger.getKey(), syncopeLogger);
}
- LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
-
/*
* Traverse all defined log4j loggers: if there is a matching SyncopeLogger, set log4j level accordingly,
* otherwise create a SyncopeLogger instance with given name and level.
@@ -95,4 +140,19 @@ public class LoggerLoader implements SyncopeLoader {
ctx.updateLoggers();
}
+
+ private static class DataSourceConnectionSource implements ConnectionSource {
+
+ private final DataSource dataSource;
+
+ public DataSourceConnectionSource(final DataSource dataSource) {
+ this.dataSource = dataSource;
+ }
+
+ @Override
+ public Connection getConnection() throws SQLException {
+ return DataSourceUtils.getConnection(dataSource);
+ }
+
+ }
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/logic/src/main/java/org/apache/syncope/core/logic/init/LogicInitializer.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/init/LogicInitializer.java b/core/logic/src/main/java/org/apache/syncope/core/logic/init/LogicInitializer.java
index 9ae6aa9..856fa13 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/init/LogicInitializer.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/init/LogicInitializer.java
@@ -23,6 +23,7 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.SyncopeLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -61,6 +62,8 @@ public class LogicInitializer implements InitializingBean, BeanFactoryAware {
}
});
+ ApplicationContextProvider.setBeanFactory(beanFactory);
+
LOG.debug("Starting initialization...");
for (SyncopeLoader loader : loaders) {
LOG.debug("Invoking {} with priority {}", AopUtils.getTargetClass(loader).getName(), loader.getPriority());
http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJob.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJob.java b/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJob.java
index 9e40ff1..a0f21f3 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJob.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJob.java
@@ -18,21 +18,8 @@
*/
package org.apache.syncope.core.logic.notification;
-import java.util.Date;
-import java.util.Properties;
-import javax.mail.internet.MimeMessage;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.types.AuditElements;
-import org.apache.syncope.common.lib.types.AuditElements.Result;
-import org.apache.syncope.common.lib.types.TaskType;
-import org.apache.syncope.common.lib.types.TraceLevel;
-import org.apache.syncope.core.persistence.api.dao.TaskDAO;
-import org.apache.syncope.core.persistence.api.entity.EntityFactory;
-import org.apache.syncope.core.persistence.api.entity.task.NotificationTask;
-import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
-import org.apache.syncope.core.misc.AuditManager;
-import org.apache.syncope.core.misc.ExceptionUtils2;
-import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
+import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.persistence.api.DomainsHolder;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
@@ -40,15 +27,12 @@ import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.mail.javamail.JavaMailSender;
-import org.springframework.mail.javamail.JavaMailSenderImpl;
-import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
/**
* Periodically checks for notification to send.
*
- * @see NotificationTask
+ * @see org.apache.syncope.core.persistence.api.entity.task.NotificationTask
*/
@Component
@DisallowConcurrentExecution
@@ -63,221 +47,30 @@ public class NotificationJob implements Job {
public static final String DEFAULT_CRON_EXP = "0 0/5 * * * ?";
- /**
- * Logger.
- */
private static final Logger LOG = LoggerFactory.getLogger(NotificationJob.class);
@Autowired
- private AuditManager auditManager;
+ private DomainsHolder domainsHolder;
@Autowired
- private NotificationManager notificationManager;
-
- @Autowired
- private JavaMailSender mailSender;
-
- @Autowired
- private EntityFactory entityFactory;
-
- /**
- * Task DAO.
- */
- @Autowired
- private TaskDAO taskDAO;
-
- private long maxRetries;
-
- private void init() {
- maxRetries = notificationManager.getMaxRetries();
-
- if (mailSender instanceof JavaMailSenderImpl
- && StringUtils.isNotBlank(((JavaMailSenderImpl) mailSender).getUsername())) {
-
- Properties javaMailProperties = ((JavaMailSenderImpl) mailSender).getJavaMailProperties();
- javaMailProperties.setProperty("mail.smtp.auth", "true");
- ((JavaMailSenderImpl) mailSender).setJavaMailProperties(javaMailProperties);
- }
- }
-
- public TaskExec executeSingle(final NotificationTask task) {
- init();
-
- TaskExec execution = entityFactory.newEntity(TaskExec.class);
- execution.setTask(task);
- execution.setStartDate(new Date());
-
- boolean retryPossible = true;
-
- if (StringUtils.isBlank(task.getSubject()) || task.getRecipients().isEmpty()
- || StringUtils.isBlank(task.getHtmlBody()) || StringUtils.isBlank(task.getTextBody())) {
-
- String message = "Could not fetch all required information for sending e-mails:\n"
- + task.getRecipients() + "\n"
- + task.getSender() + "\n"
- + task.getSubject() + "\n"
- + task.getHtmlBody() + "\n"
- + task.getTextBody();
- LOG.error(message);
-
- execution.setStatus(Status.NOT_SENT.name());
- retryPossible = false;
-
- if (task.getTraceLevel().ordinal() >= TraceLevel.FAILURES.ordinal()) {
- execution.setMessage(message);
- }
- } else {
- if (LOG.isDebugEnabled()) {
- LOG.debug("About to send e-mails:\n"
- + task.getRecipients() + "\n"
- + task.getSender() + "\n"
- + task.getSubject() + "\n"
- + task.getHtmlBody() + "\n"
- + task.getTextBody() + "\n");
- }
-
- for (String to : task.getRecipients()) {
- try {
- MimeMessage message = mailSender.createMimeMessage();
- MimeMessageHelper helper = new MimeMessageHelper(message, true);
- helper.setTo(to);
- helper.setFrom(task.getSender());
- helper.setSubject(task.getSubject());
- helper.setText(task.getTextBody(), task.getHtmlBody());
-
- mailSender.send(message);
-
- execution.setStatus(Status.SENT.name());
-
- StringBuilder report = new StringBuilder();
- switch (task.getTraceLevel()) {
- case ALL:
- report.append("FROM: ").append(task.getSender()).append('\n').
- append("TO: ").append(to).append('\n').
- append("SUBJECT: ").append(task.getSubject()).append('\n').append('\n').
- append(task.getTextBody()).append('\n').append('\n').
- append(task.getHtmlBody()).append('\n');
- break;
-
- case SUMMARY:
- report.append("E-mail sent to ").append(to).append('\n');
- break;
-
- case FAILURES:
- case NONE:
- default:
- }
- if (report.length() > 0) {
- execution.setMessage(report.toString());
- }
-
- auditManager.audit(
- AuditElements.EventCategoryType.TASK,
- "notification",
- null,
- "send",
- Result.SUCCESS,
- null,
- null,
- task,
- "Successfully sent notification to " + to);
- } catch (Exception e) {
- LOG.error("Could not send e-mail", e);
-
- execution.setStatus(Status.NOT_SENT.name());
- if (task.getTraceLevel().ordinal() >= TraceLevel.FAILURES.ordinal()) {
- execution.setMessage(ExceptionUtils2.getFullStackTrace(e));
- }
-
- auditManager.audit(
- AuditElements.EventCategoryType.TASK,
- "notification",
- null,
- "send",
- Result.FAILURE,
- null,
- null,
- task,
- "Could not send notification to " + to, e);
- }
-
- execution.setEndDate(new Date());
- }
- }
-
- if (hasToBeRegistered(execution)) {
- execution = notificationManager.storeExec(execution);
- if (retryPossible && (Status.valueOf(execution.getStatus()) == Status.NOT_SENT)) {
- handleRetries(execution);
- }
- } else {
- notificationManager.setTaskExecuted(execution.getTask().getKey(), true);
- }
-
- return execution;
- }
+ private NotificationJobDelegate delegate;
@Override
- public void execute(final JobExecutionContext context)
- throws JobExecutionException {
-
+ public void execute(final JobExecutionContext context) throws JobExecutionException {
LOG.debug("Waking up...");
- for (NotificationTask task : taskDAO.<NotificationTask>findToExec(TaskType.NOTIFICATION)) {
- LOG.debug("Found notification task {} to be executed: starting...", task);
- executeSingle(task);
- LOG.debug("Notification task {} executed", task);
+ for (String domain : domainsHolder.getDomains().keySet()) {
+ AuthContextUtils.setFakeAuth(domain);
+ try {
+ delegate.execute();
+ } catch (Exception e) {
+ throw new JobExecutionException(e);
+ } finally {
+ AuthContextUtils.clearFakeAuth();
+ }
}
LOG.debug("Sleeping again...");
}
- private boolean hasToBeRegistered(final TaskExec execution) {
- NotificationTask task = (NotificationTask) execution.getTask();
-
- // True if either failed and failures have to be registered, or if ALL
- // has to be registered.
- return (Status.valueOf(execution.getStatus()) == Status.NOT_SENT
- && task.getTraceLevel().ordinal() >= TraceLevel.FAILURES.ordinal())
- || task.getTraceLevel() == TraceLevel.ALL;
- }
-
- private void handleRetries(final TaskExec execution) {
- if (maxRetries <= 0) {
- return;
- }
-
- long failedExecutionsCount = notificationManager.countExecutionsWithStatus(
- execution.getTask().getKey(), Status.NOT_SENT.name());
-
- if (failedExecutionsCount <= maxRetries) {
- LOG.debug("Execution of notification task {} will be retried [{}/{}]",
- execution.getTask(), failedExecutionsCount, maxRetries);
- notificationManager.setTaskExecuted(execution.getTask().getKey(), false);
-
- auditManager.audit(
- AuditElements.EventCategoryType.TASK,
- "notification",
- null,
- "retry",
- Result.SUCCESS,
- null,
- null,
- execution,
- "Notification task " + execution.getTask().getKey() + " will be retried");
- } else {
- LOG.error("Maximum number of retries reached for task {} - giving up", execution.getTask());
-
- auditManager.audit(
- AuditElements.EventCategoryType.TASK,
- "notification",
- null,
- "retry",
- Result.FAILURE,
- null,
- null,
- execution,
- "Giving up retries on notification task " + execution.getTask().getKey());
- }
- }
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJobDelegate.java b/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJobDelegate.java
new file mode 100644
index 0000000..aaebe77
--- /dev/null
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/notification/NotificationJobDelegate.java
@@ -0,0 +1,258 @@
+/*
+ * 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.notification;
+
+import java.util.Date;
+import java.util.Properties;
+import javax.mail.internet.MimeMessage;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.types.AuditElements;
+import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.common.lib.types.TraceLevel;
+import org.apache.syncope.core.misc.AuditManager;
+import org.apache.syncope.core.misc.ExceptionUtils2;
+import org.apache.syncope.core.persistence.api.dao.TaskDAO;
+import org.apache.syncope.core.persistence.api.entity.EntityFactory;
+import org.apache.syncope.core.persistence.api.entity.task.NotificationTask;
+import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
+import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
+import org.quartz.JobExecutionException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.mail.javamail.JavaMailSender;
+import org.springframework.mail.javamail.JavaMailSenderImpl;
+import org.springframework.mail.javamail.MimeMessageHelper;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+@Component
+public class NotificationJobDelegate {
+
+ private static final Logger LOG = LoggerFactory.getLogger(NotificationJobDelegate.class);
+
+ /**
+ * Task DAO.
+ */
+ @Autowired
+ private TaskDAO taskDAO;
+
+ @Autowired
+ private JavaMailSender mailSender;
+
+ @Autowired
+ private EntityFactory entityFactory;
+
+ @Autowired
+ private AuditManager auditManager;
+
+ @Autowired
+ private NotificationManager notificationManager;
+
+ private long maxRetries;
+
+ private void init() {
+ maxRetries = notificationManager.getMaxRetries();
+
+ if (mailSender instanceof JavaMailSenderImpl
+ && StringUtils.isNotBlank(((JavaMailSenderImpl) mailSender).getUsername())) {
+
+ Properties javaMailProperties = ((JavaMailSenderImpl) mailSender).getJavaMailProperties();
+ javaMailProperties.setProperty("mail.smtp.auth", "true");
+ ((JavaMailSenderImpl) mailSender).setJavaMailProperties(javaMailProperties);
+ }
+ }
+
+ @Transactional
+ public TaskExec executeSingle(final NotificationTask task) {
+ init();
+
+ TaskExec execution = entityFactory.newEntity(TaskExec.class);
+ execution.setTask(task);
+ execution.setStartDate(new Date());
+
+ boolean retryPossible = true;
+
+ if (StringUtils.isBlank(task.getSubject()) || task.getRecipients().isEmpty()
+ || StringUtils.isBlank(task.getHtmlBody()) || StringUtils.isBlank(task.getTextBody())) {
+
+ String message = "Could not fetch all required information for sending e-mails:\n"
+ + task.getRecipients() + "\n"
+ + task.getSender() + "\n"
+ + task.getSubject() + "\n"
+ + task.getHtmlBody() + "\n"
+ + task.getTextBody();
+ LOG.error(message);
+
+ execution.setStatus(NotificationJob.Status.NOT_SENT.name());
+ retryPossible = false;
+
+ if (task.getTraceLevel().ordinal() >= TraceLevel.FAILURES.ordinal()) {
+ execution.setMessage(message);
+ }
+ } else {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("About to send e-mails:\n"
+ + task.getRecipients() + "\n"
+ + task.getSender() + "\n"
+ + task.getSubject() + "\n"
+ + task.getHtmlBody() + "\n"
+ + task.getTextBody() + "\n");
+ }
+
+ for (String to : task.getRecipients()) {
+ try {
+ MimeMessage message = mailSender.createMimeMessage();
+ MimeMessageHelper helper = new MimeMessageHelper(message, true);
+ helper.setTo(to);
+ helper.setFrom(task.getSender());
+ helper.setSubject(task.getSubject());
+ helper.setText(task.getTextBody(), task.getHtmlBody());
+
+ mailSender.send(message);
+
+ execution.setStatus(NotificationJob.Status.SENT.name());
+
+ StringBuilder report = new StringBuilder();
+ switch (task.getTraceLevel()) {
+ case ALL:
+ report.append("FROM: ").append(task.getSender()).append('\n').
+ append("TO: ").append(to).append('\n').
+ append("SUBJECT: ").append(task.getSubject()).append('\n').append('\n').
+ append(task.getTextBody()).append('\n').append('\n').
+ append(task.getHtmlBody()).append('\n');
+ break;
+
+ case SUMMARY:
+ report.append("E-mail sent to ").append(to).append('\n');
+ break;
+
+ case FAILURES:
+ case NONE:
+ default:
+ }
+ if (report.length() > 0) {
+ execution.setMessage(report.toString());
+ }
+
+ auditManager.audit(
+ AuditElements.EventCategoryType.TASK,
+ "notification",
+ null,
+ "send",
+ AuditElements.Result.SUCCESS,
+ null,
+ null,
+ task,
+ "Successfully sent notification to " + to);
+ } catch (Exception e) {
+ LOG.error("Could not send e-mail", e);
+
+ execution.setStatus(NotificationJob.Status.NOT_SENT.name());
+ if (task.getTraceLevel().ordinal() >= TraceLevel.FAILURES.ordinal()) {
+ execution.setMessage(ExceptionUtils2.getFullStackTrace(e));
+ }
+
+ auditManager.audit(
+ AuditElements.EventCategoryType.TASK,
+ "notification",
+ null,
+ "send",
+ AuditElements.Result.FAILURE,
+ null,
+ null,
+ task,
+ "Could not send notification to " + to, e);
+ }
+
+ execution.setEndDate(new Date());
+ }
+ }
+
+ if (hasToBeRegistered(execution)) {
+ execution = notificationManager.storeExec(execution);
+ if (retryPossible && (NotificationJob.Status.valueOf(execution.getStatus())
+ == NotificationJob.Status.NOT_SENT)) {
+ handleRetries(execution);
+ }
+ } else {
+ notificationManager.setTaskExecuted(execution.getTask().getKey(), true);
+ }
+
+ return execution;
+ }
+
+ @Transactional
+ public void execute() throws JobExecutionException {
+ for (NotificationTask task : taskDAO.<NotificationTask>findToExec(TaskType.NOTIFICATION)) {
+ LOG.debug("Found notification task {} to be executed: starting...", task);
+ executeSingle(task);
+ LOG.debug("Notification task {} executed", task);
+ }
+ }
+
+ private boolean hasToBeRegistered(final TaskExec execution) {
+ NotificationTask task = (NotificationTask) execution.getTask();
+
+ // True if either failed and failures have to be registered, or if ALL
+ // has to be registered.
+ return (NotificationJob.Status.valueOf(execution.getStatus()) == NotificationJob.Status.NOT_SENT
+ && task.getTraceLevel().ordinal() >= TraceLevel.FAILURES.ordinal())
+ || task.getTraceLevel() == TraceLevel.ALL;
+ }
+
+ private void handleRetries(final TaskExec execution) {
+ if (maxRetries <= 0) {
+ return;
+ }
+
+ long failedExecutionsCount = notificationManager.countExecutionsWithStatus(
+ execution.getTask().getKey(), NotificationJob.Status.NOT_SENT.name());
+
+ if (failedExecutionsCount <= maxRetries) {
+ LOG.debug("Execution of notification task {} will be retried [{}/{}]",
+ execution.getTask(), failedExecutionsCount, maxRetries);
+ notificationManager.setTaskExecuted(execution.getTask().getKey(), false);
+
+ auditManager.audit(
+ AuditElements.EventCategoryType.TASK,
+ "notification",
+ null,
+ "retry",
+ AuditElements.Result.SUCCESS,
+ null,
+ null,
+ execution,
+ "Notification task " + execution.getTask().getKey() + " will be retried");
+ } else {
+ LOG.error("Maximum number of retries reached for task {} - giving up", execution.getTask());
+
+ auditManager.audit(
+ AuditElements.EventCategoryType.TASK,
+ "notification",
+ null,
+ "retry",
+ AuditElements.Result.FAILURE,
+ null,
+ null,
+ execution,
+ "Giving up retries on notification task " + execution.getTask().getKey());
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJob.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJob.java b/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJob.java
index e07612a..8e5af91 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJob.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJob.java
@@ -18,74 +18,28 @@
*/
package org.apache.syncope.core.logic.report;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.Date;
-import java.util.zip.Deflater;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipOutputStream;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.sax.SAXTransformerFactory;
-import javax.xml.transform.sax.TransformerHandler;
-import javax.xml.transform.stream.StreamResult;
-import org.apache.commons.io.IOUtils;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.report.ReportletConf;
-import org.apache.syncope.common.lib.types.ReportExecStatus;
-import org.apache.syncope.core.persistence.api.dao.ReportDAO;
-import org.apache.syncope.core.persistence.api.dao.ReportExecDAO;
-import org.apache.syncope.core.persistence.api.entity.EntityFactory;
-import org.apache.syncope.core.persistence.api.entity.Report;
-import org.apache.syncope.core.persistence.api.entity.ReportExec;
-import org.apache.syncope.core.logic.ReportLogic;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
-import org.apache.syncope.core.misc.ExceptionUtils2;
+import org.apache.syncope.core.misc.security.AuthContextUtils;
+import org.apache.syncope.core.provisioning.api.job.JobInstanceLoader;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.support.AbstractBeanDefinition;
-import org.xml.sax.helpers.AttributesImpl;
/**
* Quartz job for executing a given report.
*/
-@SuppressWarnings("unchecked")
@DisallowConcurrentExecution
public class ReportJob implements Job {
/**
- * Logger.
- */
- private static final Logger LOG = LoggerFactory.getLogger(ReportJob.class);
-
- /**
- * Report DAO.
- */
- @Autowired
- private ReportDAO reportDAO;
-
- /**
- * Report execution DAO.
- */
- @Autowired
- private ReportExecDAO reportExecDAO;
-
- @Autowired
- private ReportLogic dataBinder;
-
- @Autowired
- private EntityFactory entityFactory;
-
- /**
* Key, set by the caller, for identifying the report to be executed.
*/
private Long reportKey;
+ @Autowired
+ private ReportJobDelegate delegate;
+
/**
* Report id setter.
*
@@ -95,109 +49,15 @@ public class ReportJob implements Job {
this.reportKey = reportKey;
}
- @SuppressWarnings("rawtypes")
@Override
public void execute(final JobExecutionContext context) throws JobExecutionException {
- Report report = reportDAO.find(reportKey);
- if (report == null) {
- throw new JobExecutionException("Report " + reportKey + " not found");
- }
-
- // 1. create execution
- ReportExec execution = entityFactory.newEntity(ReportExec.class);
- execution.setStatus(ReportExecStatus.STARTED);
- execution.setStartDate(new Date());
- execution.setReport(report);
- execution = reportExecDAO.save(execution);
-
- report.addExec(execution);
- report = reportDAO.save(report);
-
- // 2. define a SAX handler for generating result as XML
- TransformerHandler handler;
-
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- ZipOutputStream zos = new ZipOutputStream(baos);
- zos.setLevel(Deflater.BEST_COMPRESSION);
- try {
- SAXTransformerFactory tFactory = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
- handler = tFactory.newTransformerHandler();
- Transformer serializer = handler.getTransformer();
- serializer.setOutputProperty(OutputKeys.ENCODING, SyncopeConstants.DEFAULT_ENCODING);
- serializer.setOutputProperty(OutputKeys.INDENT, "yes");
-
- // a single ZipEntry in the ZipOutputStream
- zos.putNextEntry(new ZipEntry(report.getName()));
-
- // streaming SAX handler in a compressed byte array stream
- handler.setResult(new StreamResult(zos));
- } catch (Exception e) {
- throw new JobExecutionException("While configuring for SAX generation", e, true);
- }
-
- execution.setStatus(ReportExecStatus.RUNNING);
- execution = reportExecDAO.save(execution);
-
- // 3. actual report execution
- StringBuilder reportExecutionMessage = new StringBuilder();
+ AuthContextUtils.setFakeAuth(context.getMergedJobDataMap().getString(JobInstanceLoader.DOMAIN));
try {
- // report header
- handler.startDocument();
- AttributesImpl atts = new AttributesImpl();
- atts.addAttribute("", "", ReportXMLConst.ATTR_NAME, ReportXMLConst.XSD_STRING, report.getName());
- handler.startElement("", "", ReportXMLConst.ELEMENT_REPORT, atts);
-
- // iterate over reportlet instances defined for this report
- for (ReportletConf reportletConf : report.getReportletConfs()) {
- Class<Reportlet> reportletClass =
- dataBinder.findReportletClassHavingConfClass(reportletConf.getClass());
- if (reportletClass != null) {
- Reportlet<ReportletConf> autowired =
- (Reportlet<ReportletConf>) ApplicationContextProvider.getBeanFactory().
- createBean(reportletClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false);
- autowired.setConf(reportletConf);
-
- // invoke reportlet
- try {
- autowired.extract(handler);
- } catch (Exception e) {
- execution.setStatus(ReportExecStatus.FAILURE);
-
- Throwable t = e instanceof ReportException
- ? e.getCause()
- : e;
- reportExecutionMessage.
- append(ExceptionUtils2.getFullStackTrace(t)).
- append("\n==================\n");
- }
- }
- }
-
- // report footer
- handler.endElement("", "", ReportXMLConst.ELEMENT_REPORT);
- handler.endDocument();
-
- if (!ReportExecStatus.FAILURE.name().equals(execution.getStatus())) {
- execution.setStatus(ReportExecStatus.SUCCESS);
- }
+ delegate.execute(reportKey);
} catch (Exception e) {
- execution.setStatus(ReportExecStatus.FAILURE);
- reportExecutionMessage.append(ExceptionUtils2.getFullStackTrace(e));
-
- throw new JobExecutionException(e, true);
+ throw new JobExecutionException(e);
} finally {
- try {
- zos.closeEntry();
- IOUtils.closeQuietly(zos);
- IOUtils.closeQuietly(baos);
- } catch (IOException e) {
- LOG.error("While closing StreamResult's backend", e);
- }
-
- execution.setExecResult(baos.toByteArray());
- execution.setMessage(reportExecutionMessage.toString());
- execution.setEndDate(new Date());
- reportExecDAO.save(execution);
+ AuthContextUtils.clearFakeAuth();
}
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJobDelegate.java b/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJobDelegate.java
new file mode 100644
index 0000000..9920c1f
--- /dev/null
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/report/ReportJobDelegate.java
@@ -0,0 +1,181 @@
+/*
+ * 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.report;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Date;
+import java.util.zip.Deflater;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.sax.SAXTransformerFactory;
+import javax.xml.transform.sax.TransformerHandler;
+import javax.xml.transform.stream.StreamResult;
+import org.apache.commons.io.IOUtils;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.report.ReportletConf;
+import org.apache.syncope.common.lib.types.ReportExecStatus;
+import org.apache.syncope.core.logic.ReportLogic;
+import org.apache.syncope.core.misc.ExceptionUtils2;
+import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.persistence.api.dao.ReportDAO;
+import org.apache.syncope.core.persistence.api.dao.ReportExecDAO;
+import org.apache.syncope.core.persistence.api.entity.EntityFactory;
+import org.apache.syncope.core.persistence.api.entity.Report;
+import org.apache.syncope.core.persistence.api.entity.ReportExec;
+import org.quartz.JobExecutionException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+import org.xml.sax.helpers.AttributesImpl;
+
+@Component
+public class ReportJobDelegate {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ReportJobDelegate.class);
+
+ /**
+ * Report DAO.
+ */
+ @Autowired
+ private ReportDAO reportDAO;
+
+ /**
+ * Report execution DAO.
+ */
+ @Autowired
+ private ReportExecDAO reportExecDAO;
+
+ @Autowired
+ private EntityFactory entityFactory;
+
+ @Autowired
+ private ReportLogic dataBinder;
+
+ @Transactional
+ public void execute(final Long reportKey) throws JobExecutionException {
+ Report report = reportDAO.find(reportKey);
+ if (report == null) {
+ throw new JobExecutionException("Report " + reportKey + " not found");
+ }
+
+ // 1. create execution
+ ReportExec execution = entityFactory.newEntity(ReportExec.class);
+ execution.setStatus(ReportExecStatus.STARTED);
+ execution.setStartDate(new Date());
+ execution.setReport(report);
+ execution = reportExecDAO.save(execution);
+
+ report.addExec(execution);
+ report = reportDAO.save(report);
+
+ // 2. define a SAX handler for generating result as XML
+ TransformerHandler handler;
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ZipOutputStream zos = new ZipOutputStream(baos);
+ zos.setLevel(Deflater.BEST_COMPRESSION);
+ try {
+ SAXTransformerFactory tFactory = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
+ handler = tFactory.newTransformerHandler();
+ Transformer serializer = handler.getTransformer();
+ serializer.setOutputProperty(OutputKeys.ENCODING, SyncopeConstants.DEFAULT_ENCODING);
+ serializer.setOutputProperty(OutputKeys.INDENT, "yes");
+
+ // a single ZipEntry in the ZipOutputStream
+ zos.putNextEntry(new ZipEntry(report.getName()));
+
+ // streaming SAX handler in a compressed byte array stream
+ handler.setResult(new StreamResult(zos));
+ } catch (Exception e) {
+ throw new JobExecutionException("While configuring for SAX generation", e, true);
+ }
+
+ execution.setStatus(ReportExecStatus.RUNNING);
+ execution = reportExecDAO.save(execution);
+
+ // 3. actual report execution
+ StringBuilder reportExecutionMessage = new StringBuilder();
+ try {
+ // report header
+ handler.startDocument();
+ AttributesImpl atts = new AttributesImpl();
+ atts.addAttribute("", "", ReportXMLConst.ATTR_NAME, ReportXMLConst.XSD_STRING, report.getName());
+ handler.startElement("", "", ReportXMLConst.ELEMENT_REPORT, atts);
+
+ // iterate over reportlet instances defined for this report
+ for (ReportletConf reportletConf : report.getReportletConfs()) {
+ Class<Reportlet> reportletClass =
+ dataBinder.findReportletClassHavingConfClass(reportletConf.getClass());
+ if (reportletClass != null) {
+ @SuppressWarnings("unchecked")
+ Reportlet<ReportletConf> autowired =
+ (Reportlet<ReportletConf>) ApplicationContextProvider.getBeanFactory().
+ createBean(reportletClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false);
+ autowired.setConf(reportletConf);
+
+ // invoke reportlet
+ try {
+ autowired.extract(handler);
+ } catch (Exception e) {
+ execution.setStatus(ReportExecStatus.FAILURE);
+
+ Throwable t = e instanceof ReportException
+ ? e.getCause()
+ : e;
+ reportExecutionMessage.
+ append(ExceptionUtils2.getFullStackTrace(t)).
+ append("\n==================\n");
+ }
+ }
+ }
+
+ // report footer
+ handler.endElement("", "", ReportXMLConst.ELEMENT_REPORT);
+ handler.endDocument();
+
+ if (!ReportExecStatus.FAILURE.name().equals(execution.getStatus())) {
+ execution.setStatus(ReportExecStatus.SUCCESS);
+ }
+ } catch (Exception e) {
+ execution.setStatus(ReportExecStatus.FAILURE);
+ reportExecutionMessage.append(ExceptionUtils2.getFullStackTrace(e));
+
+ throw new JobExecutionException(e, true);
+ } finally {
+ try {
+ zos.closeEntry();
+ IOUtils.closeQuietly(zos);
+ IOUtils.closeQuietly(baos);
+ } catch (IOException e) {
+ LOG.error("While closing StreamResult's backend", e);
+ }
+
+ execution.setExecResult(baos.toByteArray());
+ execution.setMessage(reportExecutionMessage.toString());
+ execution.setEndDate(new Date());
+ reportExecDAO.save(execution);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/logic/src/test/java/org/apache/syncope/core/logic/AbstractTest.java
----------------------------------------------------------------------
diff --git a/core/logic/src/test/java/org/apache/syncope/core/logic/AbstractTest.java b/core/logic/src/test/java/org/apache/syncope/core/logic/AbstractTest.java
index 161d0c1..d4b0fa4 100644
--- a/core/logic/src/test/java/org/apache/syncope/core/logic/AbstractTest.java
+++ b/core/logic/src/test/java/org/apache/syncope/core/logic/AbstractTest.java
@@ -23,7 +23,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-import org.springframework.transaction.annotation.Transactional;
+import org.springframework.test.context.transaction.TransactionConfiguration;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
@@ -33,7 +33,7 @@ import org.springframework.transaction.annotation.Transactional;
"classpath:persistenceTest.xml",
"classpath:logicTest.xml"
})
-@Transactional
+@TransactionConfiguration(transactionManager = "MasterTransactionManager")
public abstract class AbstractTest {
protected static final Logger LOG = LoggerFactory.getLogger(AbstractTest.class);
http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/logic/src/test/java/org/apache/syncope/core/logic/MappingTest.java
----------------------------------------------------------------------
diff --git a/core/logic/src/test/java/org/apache/syncope/core/logic/MappingTest.java b/core/logic/src/test/java/org/apache/syncope/core/logic/MappingTest.java
index 1f1dab7..770bac9 100644
--- a/core/logic/src/test/java/org/apache/syncope/core/logic/MappingTest.java
+++ b/core/logic/src/test/java/org/apache/syncope/core/logic/MappingTest.java
@@ -31,7 +31,9 @@ import org.apache.syncope.core.persistence.api.entity.user.User;
import org.identityconnectors.framework.common.objects.Name;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+@Transactional
public class MappingTest extends AbstractTest {
@Autowired
http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/logic/src/test/java/org/apache/syncope/core/logic/NotificationTest.java
----------------------------------------------------------------------
diff --git a/core/logic/src/test/java/org/apache/syncope/core/logic/NotificationTest.java b/core/logic/src/test/java/org/apache/syncope/core/logic/NotificationTest.java
index c5dc13c..6c208a2 100644
--- a/core/logic/src/test/java/org/apache/syncope/core/logic/NotificationTest.java
+++ b/core/logic/src/test/java/org/apache/syncope/core/logic/NotificationTest.java
@@ -79,7 +79,9 @@ import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.transaction.annotation.Transactional;
+@Transactional
public class NotificationTest extends AbstractTest {
private static final String SMTP_HOST = "localhost";
@@ -164,7 +166,7 @@ public class NotificationTest extends AbstractTest {
}
private static UserTO getSampleTO(final String email) {
- String uid = email;
+ String uid = UUID.randomUUID().toString().substring(0, 8) + email;
UserTO userTO = new UserTO();
userTO.setPassword("password123");
userTO.setUsername(uid);
@@ -175,7 +177,7 @@ public class NotificationTest extends AbstractTest {
userTO.getPlainAttrs().add(attributeTO("surname", "surname"));
userTO.getPlainAttrs().add(attributeTO("type", "a type"));
userTO.getPlainAttrs().add(attributeTO("userId", uid));
- userTO.getPlainAttrs().add(attributeTO("email", uid));
+ userTO.getPlainAttrs().add(attributeTO("email", email));
userTO.getPlainAttrs().add(attributeTO("loginDate", new SimpleDateFormat("yyyy-MM-dd").format(new Date())));
userTO.getDerAttrs().add(attributeTO("cn", null));
userTO.getVirAttrs().add(attributeTO("virtualdata", "virtualvalue"));
http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/logic/src/test/resources/logicTest.xml
----------------------------------------------------------------------
diff --git a/core/logic/src/test/resources/logicTest.xml b/core/logic/src/test/resources/logicTest.xml
index 3cf0ab0..2dca918 100644
--- a/core/logic/src/test/resources/logicTest.xml
+++ b/core/logic/src/test/resources/logicTest.xml
@@ -26,6 +26,7 @@ under the License.
<property name="locations">
<list>
<value>classpath:persistence.properties</value>
+ <value>classpath:domains/*.properties</value>
<value>classpath:security.properties</value>
<value>classpath:connid.properties</value>
<value>classpath:mail.properties</value>
@@ -37,10 +38,5 @@ under the License.
<property name="ignoreResourceNotFound" value="true"/>
<property name="ignoreUnresolvablePlaceholders" value="true"/>
</bean>
-
- <bean id="contentXML" class="org.apache.syncope.core.misc.spring.ResourceWithFallbackLoader">
- <property name="primary" value="file:${conf.directory}/content.xml"/>
- <property name="fallback" value="classpath:content.xml"/>
- </bean>
</beans>
http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/misc/src/main/java/org/apache/syncope/core/misc/AuditManager.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/AuditManager.java b/core/misc/src/main/java/org/apache/syncope/core/misc/AuditManager.java
index a8d8aac..d370895 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/AuditManager.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/AuditManager.java
@@ -23,13 +23,18 @@ 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.misc.security.AuthContextUtils;
+import org.apache.syncope.core.misc.security.SyncopeAuthenticationDetails;
import org.apache.syncope.core.persistence.api.dao.LoggerDAO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
@Component
public class AuditManager {
@@ -39,6 +44,11 @@ public class AuditManager {
@Autowired
private LoggerDAO loggerDAO;
+ public static String getDomainAuditLoggerName(final String domain) {
+ return LoggerType.AUDIT.getPrefix() + "." + domain;
+ }
+
+ @Transactional(readOnly = true)
public void audit(
final AuditElements.EventCategoryType type,
final String category,
@@ -88,13 +98,22 @@ public class AuditManager {
if (syncopeLogger != null && syncopeLogger.getLevel() == LoggerLevel.DEBUG) {
StringBuilder auditMessage = new StringBuilder();
- final SecurityContext ctx = SecurityContextHolder.getContext();
+ SecurityContext ctx = SecurityContextHolder.getContext();
if (ctx != null && ctx.getAuthentication() != null) {
auditMessage.append('[').append(ctx.getAuthentication().getName()).append("] ");
}
auditMessage.append(message);
- final Logger logger = LoggerFactory.getLogger(auditLoggerName.toLoggerName());
+ String domain = AuthContextUtils.getDomain();
+ if (input != null && input.length > 0 && input[0] instanceof UsernamePasswordAuthenticationToken) {
+ UsernamePasswordAuthenticationToken token =
+ UsernamePasswordAuthenticationToken.class.cast(input[0]);
+ if (token.getDetails() instanceof SyncopeAuthenticationDetails) {
+ domain = SyncopeAuthenticationDetails.class.cast(token.getDetails()).getDomain();
+ }
+ }
+
+ Logger logger = LoggerFactory.getLogger(getDomainAuditLoggerName(domain));
if (throwable == null) {
logger.debug(auditMessage.toString());
} else {
http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/misc/src/main/java/org/apache/syncope/core/misc/MappingUtils.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/MappingUtils.java b/core/misc/src/main/java/org/apache/syncope/core/misc/MappingUtils.java
index e655809..95a16b1 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/MappingUtils.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/MappingUtils.java
@@ -73,7 +73,7 @@ import org.identityconnectors.framework.common.objects.Name;
import org.identityconnectors.framework.common.objects.OperationalAttributes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
public final class MappingUtils {
@@ -141,9 +141,9 @@ public final class MappingUtils {
LOG.debug("Preparing resource attributes for {} with provision {} for attributes {}",
any, provision, any.getPlainAttrs());
- ConfigurableApplicationContext context = ApplicationContextProvider.getApplicationContext();
- VirAttrCache virAttrCache = context.getBean(VirAttrCache.class);
- PasswordGenerator passwordGenerator = context.getBean(PasswordGenerator.class);
+ DefaultListableBeanFactory beanFactory = ApplicationContextProvider.getBeanFactory();
+ VirAttrCache virAttrCache = beanFactory.getBean(VirAttrCache.class);
+ PasswordGenerator passwordGenerator = beanFactory.getBean(PasswordGenerator.class);
Set<Attribute> attributes = new HashSet<>();
String connObjectKey = null;
@@ -227,9 +227,9 @@ public final class MappingUtils {
List<Any<?, ?, ?>> anys = new ArrayList<>();
- ConfigurableApplicationContext context = ApplicationContextProvider.getApplicationContext();
- AnyUtilsFactory anyUtilsFactory = context.getBean(AnyUtilsFactory.class);
- VirAttrHandler virAttrHandler = context.getBean(VirAttrHandler.class);
+ DefaultListableBeanFactory beanFactory = ApplicationContextProvider.getBeanFactory();
+ AnyUtilsFactory anyUtilsFactory = beanFactory.getBean(AnyUtilsFactory.class);
+ VirAttrHandler virAttrHandler = beanFactory.getBean(VirAttrHandler.class);
switch (mapItem.getIntMappingType().getAnyTypeKind()) {
case USER:
@@ -240,7 +240,7 @@ public final class MappingUtils {
case GROUP:
if (any instanceof User) {
- UserDAO userDAO = context.getBean(UserDAO.class);
+ UserDAO userDAO = beanFactory.getBean(UserDAO.class);
for (Group group : userDAO.findAllGroups((User) any)) {
virAttrHandler.retrieveVirAttrValues(group);
anys.add(group);
@@ -271,7 +271,7 @@ public final class MappingUtils {
case UserPlainSchema:
case GroupPlainSchema:
case AnyObjectPlainSchema:
- final PlainSchemaDAO plainSchemaDAO = context.getBean(PlainSchemaDAO.class);
+ PlainSchemaDAO plainSchemaDAO = beanFactory.getBean(PlainSchemaDAO.class);
schema = plainSchemaDAO.find(mapItem.getIntAttrName());
schemaType = schema == null ? AttrSchemaType.String : schema.getType();
break;
@@ -279,7 +279,7 @@ public final class MappingUtils {
case UserVirtualSchema:
case GroupVirtualSchema:
case AnyObjectVirtualSchema:
- VirSchemaDAO virSchemaDAO = context.getBean(VirSchemaDAO.class);
+ VirSchemaDAO virSchemaDAO = beanFactory.getBean(VirSchemaDAO.class);
VirSchema virSchema = virSchemaDAO.find(mapItem.getIntAttrName());
readOnlyVirSchema = (virSchema != null && virSchema.isReadonly());
schemaType = AttrSchemaType.String;
@@ -434,9 +434,9 @@ public final class MappingUtils {
LOG.debug("Get attributes for '{}' and mapping type '{}'", anys, mappingItem.getIntMappingType());
EntityFactory entityFactory =
- ApplicationContextProvider.getApplicationContext().getBean(EntityFactory.class);
+ ApplicationContextProvider.getBeanFactory().getBean(EntityFactory.class);
AnyUtilsFactory anyUtilsFactory =
- ApplicationContextProvider.getApplicationContext().getBean(AnyUtilsFactory.class);
+ ApplicationContextProvider.getBeanFactory().getBean(AnyUtilsFactory.class);
List<PlainAttrValue> values = new ArrayList<>();
PlainAttrValue attrValue;
switch (mappingItem.getIntMappingType()) {
@@ -551,7 +551,7 @@ public final class MappingUtils {
break;
case GroupOwnerSchema:
- AnyTypeDAO anyTypeDAO = ApplicationContextProvider.getApplicationContext().getBean(AnyTypeDAO.class);
+ AnyTypeDAO anyTypeDAO = ApplicationContextProvider.getBeanFactory().getBean(AnyTypeDAO.class);
Mapping uMapping = provision.getAnyType().equals(anyTypeDAO.findUser())
? null
: provision.getMapping();
http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/misc/src/main/java/org/apache/syncope/core/misc/policy/AccountPolicyEnforcer.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/AccountPolicyEnforcer.java b/core/misc/src/main/java/org/apache/syncope/core/misc/policy/AccountPolicyEnforcer.java
index 4b8faec..13ddc84 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/AccountPolicyEnforcer.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/policy/AccountPolicyEnforcer.java
@@ -22,8 +22,6 @@ import java.util.regex.Pattern;
import org.apache.syncope.common.lib.types.AccountPolicySpec;
import org.apache.syncope.common.lib.types.PolicyType;
import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.provisioning.api.UserSuspender;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
@@ -31,11 +29,8 @@ public class AccountPolicyEnforcer implements PolicyEnforcer<AccountPolicySpec,
private static final Pattern DEFAULT_PATTERN = Pattern.compile("[a-zA-Z0-9-_@. ]+");
- @Autowired(required = false)
- private UserSuspender userSuspender;
-
@Override
- public void enforce(final AccountPolicySpec policy, final PolicyType type, final User user) {
+ public boolean enforce(final AccountPolicySpec policy, final PolicyType type, final User user) {
if (user.getUsername() == null) {
throw new PolicyEnforceException("Invalid account");
}
@@ -90,11 +85,7 @@ public class AccountPolicyEnforcer implements PolicyEnforcer<AccountPolicySpec,
}
// check for subsequent failed logins
- if (userSuspender != null
- && user.getFailedLogins() != null && policy.getMaxAuthenticationAttempts() > 0
- && user.getFailedLogins() > policy.getMaxAuthenticationAttempts() && !user.isSuspended()) {
-
- userSuspender.suspend(user, policy.isPropagateSuspension());
- }
+ return (user.getFailedLogins() != null && policy.getMaxAuthenticationAttempts() > 0
+ && user.getFailedLogins() > policy.getMaxAuthenticationAttempts() && !user.isSuspended());
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/34a1c214/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PasswordPolicyEnforcer.java
----------------------------------------------------------------------
diff --git a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PasswordPolicyEnforcer.java b/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PasswordPolicyEnforcer.java
index 41a6bb6..1313d2e 100644
--- a/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PasswordPolicyEnforcer.java
+++ b/core/misc/src/main/java/org/apache/syncope/core/misc/policy/PasswordPolicyEnforcer.java
@@ -27,7 +27,7 @@ import org.springframework.stereotype.Component;
public class PasswordPolicyEnforcer implements PolicyEnforcer<PasswordPolicySpec, User> {
@Override
- public void enforce(final PasswordPolicySpec policy, final PolicyType type, final User user) {
+ public boolean enforce(final PasswordPolicySpec policy, final PolicyType type, final User user) {
final String clearPassword = user.getClearPassword();
final String password = user.getPassword();
@@ -147,6 +147,8 @@ public class PasswordPolicyEnforcer implements PolicyEnforcer<PasswordPolicySpec
throw new PasswordPolicyException("Password mustn't end with a non-alphanumeric character");
}
}
+
+ return false;
}
private boolean checkForDigit(final String str) {