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 2016/03/09 12:52:45 UTC
[09/17] syncope git commit: Further refactoring as per SYNCOPE-620
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/JexlUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/JexlUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/JexlUtils.java
new file mode 100644
index 0000000..7c6c38a
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/jexl/JexlUtils.java
@@ -0,0 +1,241 @@
+/*
+ * 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.provisioning.java.jexl;
+
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Field;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.jexl3.JexlBuilder;
+import org.apache.commons.jexl3.JexlContext;
+import org.apache.commons.jexl3.JexlEngine;
+import org.apache.commons.jexl3.JexlException;
+import org.apache.commons.jexl3.JexlExpression;
+import org.apache.commons.jexl3.JxltEngine;
+import org.apache.commons.jexl3.MapContext;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
+import org.apache.syncope.core.provisioning.api.utils.FormatUtils;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.DerSchema;
+import org.apache.syncope.core.persistence.api.entity.PlainAttr;
+import org.apache.syncope.core.provisioning.api.DerAttrHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * JEXL <a href="http://commons.apache.org/jexl/reference/index.html">reference</a> is available.
+ */
+public final class JexlUtils {
+
+ private static final Logger LOG = LoggerFactory.getLogger(JexlUtils.class);
+
+ private static final String[] IGNORE_FIELDS = { "password", "clearPassword", "serialVersionUID", "class" };
+
+ private static JexlEngine JEXL_ENGINE;
+
+ private static JexlEngine getEngine() {
+ synchronized (LOG) {
+ if (JEXL_ENGINE == null) {
+ JEXL_ENGINE = new JexlBuilder().
+ uberspect(new ClassFreeUberspect()).
+ loader(new EmptyClassLoader()).
+ cache(512).
+ silent(false).
+ strict(false).
+ create();
+ }
+ }
+
+ return JEXL_ENGINE;
+ }
+
+ public static JxltEngine newJxltEngine() {
+ return getEngine().createJxltEngine(false);
+ }
+
+ public static boolean isExpressionValid(final String expression) {
+ boolean result;
+ try {
+ getEngine().createExpression(expression);
+ result = true;
+ } catch (JexlException e) {
+ LOG.error("Invalid jexl expression: " + expression, e);
+ result = false;
+ }
+
+ return result;
+ }
+
+ public static String evaluate(final String expression, final JexlContext jexlContext) {
+ String result = StringUtils.EMPTY;
+
+ if (StringUtils.isNotBlank(expression) && jexlContext != null) {
+ try {
+ JexlExpression jexlExpression = getEngine().createExpression(expression);
+ Object evaluated = jexlExpression.evaluate(jexlContext);
+ if (evaluated != null) {
+ result = evaluated.toString();
+ }
+ } catch (Exception e) {
+ LOG.error("Error while evaluating JEXL expression: " + expression, e);
+ }
+ } else {
+ LOG.debug("Expression not provided or invalid context");
+ }
+
+ return result;
+ }
+
+ public static JexlContext addFieldsToContext(final Object object, final JexlContext jexlContext) {
+ JexlContext context = jexlContext == null ? new MapContext() : jexlContext;
+
+ try {
+ for (PropertyDescriptor desc : Introspector.getBeanInfo(object.getClass()).getPropertyDescriptors()) {
+ Class<?> type = desc.getPropertyType();
+ String fieldName = desc.getName();
+
+ if ((!fieldName.startsWith("pc"))
+ && (!ArrayUtils.contains(IGNORE_FIELDS, fieldName))
+ && (!Iterable.class.isAssignableFrom(type))
+ && (!type.isArray())) {
+
+ try {
+ Object fieldValue;
+ if (desc.getReadMethod() == null) {
+ final Field field = object.getClass().getDeclaredField(fieldName);
+ field.setAccessible(true);
+ fieldValue = field.get(object);
+ } else {
+ fieldValue = desc.getReadMethod().invoke(object);
+ }
+
+ context.set(fieldName, fieldValue == null
+ ? StringUtils.EMPTY
+ : (type.equals(Date.class)
+ ? FormatUtils.format((Date) fieldValue, false)
+ : fieldValue));
+
+ LOG.debug("Add field {} with value {}", fieldName, fieldValue);
+ } catch (Exception iae) {
+ LOG.error("Reading '{}' value error", fieldName, iae);
+ }
+ }
+ }
+ } catch (IntrospectionException ie) {
+ LOG.error("Reading class attributes error", ie);
+ }
+
+ if (object instanceof Any) {
+ Any<?> any = (Any<?>) object;
+ if (any.getRealm() != null) {
+ context.set("realm", any.getRealm().getName());
+ }
+ }
+
+ return context;
+ }
+
+ public static void addPlainAttrsToContext(
+ final Collection<? extends PlainAttr<?>> attrs, final JexlContext jexlContext) {
+
+ for (PlainAttr<?> attr : attrs) {
+ if (attr.getSchema() != null) {
+ List<String> attrValues = attr.getValuesAsStrings();
+ String expressionValue = attrValues.isEmpty()
+ ? StringUtils.EMPTY
+ : attrValues.get(0);
+
+ LOG.debug("Add attribute {} with value {}", attr.getSchema().getKey(), expressionValue);
+
+ jexlContext.set(attr.getSchema().getKey(), expressionValue);
+ }
+ }
+ }
+
+ public static void addDerAttrsToContext(final Any<?> any, final JexlContext jexlContext) {
+ Map<DerSchema, String> derAttrs =
+ ApplicationContextProvider.getBeanFactory().getBean(DerAttrHandler.class).getValues(any);
+
+ for (Map.Entry<DerSchema, String> entry : derAttrs.entrySet()) {
+ jexlContext.set(entry.getKey().getKey(), entry.getValue());
+ }
+ }
+
+ public static boolean evaluateMandatoryCondition(final String mandatoryCondition, final Any<?> any) {
+ JexlContext jexlContext = new MapContext();
+ addPlainAttrsToContext(any.getPlainAttrs(), jexlContext);
+ addDerAttrsToContext(any, jexlContext);
+
+ return Boolean.parseBoolean(evaluate(mandatoryCondition, jexlContext));
+ }
+
+ public static String evaluate(final String expression, final AnyTO anyTO) {
+ final JexlContext context = new MapContext();
+
+ addFieldsToContext(anyTO, context);
+
+ for (AttrTO plainAttr : anyTO.getPlainAttrs()) {
+ List<String> values = plainAttr.getValues();
+ String expressionValue = values.isEmpty()
+ ? StringUtils.EMPTY
+ : values.get(0);
+
+ LOG.debug("Add plain attribute {} with value {}", plainAttr.getSchema(), expressionValue);
+
+ context.set(plainAttr.getSchema(), expressionValue);
+ }
+ for (AttrTO derAttr : anyTO.getDerAttrs()) {
+ List<String> values = derAttr.getValues();
+ String expressionValue = values.isEmpty()
+ ? StringUtils.EMPTY
+ : values.get(0);
+
+ LOG.debug("Add derived attribute {} with value {}", derAttr.getSchema(), expressionValue);
+
+ context.set(derAttr.getSchema(), expressionValue);
+ }
+ for (AttrTO virAttr : anyTO.getVirAttrs()) {
+ List<String> values = virAttr.getValues();
+ String expressionValue = values.isEmpty()
+ ? StringUtils.EMPTY
+ : values.get(0);
+
+ LOG.debug("Add virtual attribute {} with value {}", virAttr.getSchema(), expressionValue);
+
+ context.set(virAttr.getSchema(), expressionValue);
+ }
+
+ // Evaluate expression using the context prepared before
+ return evaluate(expression, context);
+ }
+
+ /**
+ * Private default constructor, for static-only classes.
+ */
+ private JexlUtils() {
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractInterruptableJob.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractInterruptableJob.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractInterruptableJob.java
index bd550b5..3b22728 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractInterruptableJob.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractInterruptableJob.java
@@ -21,7 +21,7 @@ package org.apache.syncope.core.provisioning.java.job;
import java.util.Date;
import java.util.concurrent.atomic.AtomicReference;
-import org.apache.syncope.core.misc.utils.FormatUtils;
+import org.apache.syncope.core.provisioning.api.utils.FormatUtils;
import org.apache.syncope.core.provisioning.api.job.JobManager;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.InterruptableJob;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java
index ea6a525..aec8853 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java
@@ -20,13 +20,13 @@ package org.apache.syncope.core.provisioning.java.job;
import java.util.Date;
import org.apache.syncope.common.lib.types.AuditElements;
-import org.apache.syncope.core.misc.AuditManager;
-import org.apache.syncope.core.misc.utils.ExceptionUtils2;
+import org.apache.syncope.core.provisioning.api.utils.ExceptionUtils2;
import org.apache.syncope.core.persistence.api.dao.TaskDAO;
import org.apache.syncope.core.persistence.api.dao.TaskExecDAO;
import org.apache.syncope.core.persistence.api.entity.EntityFactory;
import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
+import org.apache.syncope.core.provisioning.api.AuditManager;
import org.apache.syncope.core.provisioning.api.job.SchedTaskJobDelegate;
import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
import org.quartz.JobExecutionException;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java
index 4692e88..50067dc 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java
@@ -19,8 +19,8 @@
package org.apache.syncope.core.provisioning.java.job;
import org.apache.commons.lang3.ClassUtils;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.provisioning.api.job.SchedTaskJobDelegate;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java
index 74dc39f..b119bd1 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/NotificationManagerImpl.java
@@ -37,7 +37,7 @@ import org.apache.syncope.common.lib.types.IntMappingType;
import org.apache.syncope.common.lib.to.AnyObjectTO;
import org.apache.syncope.common.lib.to.ProvisioningResult;
import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.core.misc.jexl.JexlUtils;
+import org.apache.syncope.core.provisioning.java.jexl.JexlUtils;
import org.apache.syncope.core.persistence.api.dao.ConfDAO;
import org.apache.syncope.core.persistence.api.dao.NotificationDAO;
import org.apache.syncope.core.persistence.api.dao.GroupDAO;
@@ -54,8 +54,8 @@ import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
import org.apache.syncope.core.persistence.api.entity.user.User;
import org.apache.syncope.core.provisioning.api.data.GroupDataBinder;
import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
-import org.apache.syncope.core.misc.search.SearchCondConverter;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.persistence.api.search.SearchCondConverter;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
index 7d7edc1..2c2e9ea 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/AbstractPropagationTaskExecutor.java
@@ -44,11 +44,10 @@ import org.apache.syncope.core.provisioning.api.TimeoutException;
import org.apache.syncope.core.provisioning.api.propagation.PropagationActions;
import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
-import org.apache.syncope.core.misc.AuditManager;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
-import org.apache.syncope.core.misc.utils.ConnObjectUtils;
-import org.apache.syncope.core.misc.utils.ExceptionUtils2;
-import org.apache.syncope.core.misc.utils.MappingUtils;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
+import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils;
+import org.apache.syncope.core.provisioning.api.utils.ExceptionUtils2;
+import org.apache.syncope.core.provisioning.java.MappingManagerImpl;
import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
import org.apache.syncope.core.persistence.api.entity.Any;
@@ -59,6 +58,7 @@ import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
import org.apache.syncope.core.persistence.api.entity.resource.Provision;
import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.provisioning.api.AuditManager;
import org.apache.syncope.core.provisioning.api.cache.VirAttrCache;
import org.apache.syncope.core.provisioning.api.cache.VirAttrCacheValue;
import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
@@ -574,11 +574,10 @@ public abstract class AbstractPropagationTaskExecutor implements PropagationTask
ConnectorObject obj = null;
try {
- obj = connector.getObject(
- new ObjectClass(task.getObjectClassName()),
+ obj = connector.getObject(new ObjectClass(task.getObjectClassName()),
new Uid(connObjectKey),
- MappingUtils.buildOperationOptions(IteratorUtils.chainedIterator(
- MappingUtils.getPropagationMappingItems(provision).iterator(),
+ MappingManagerImpl.buildOperationOptions(IteratorUtils.chainedIterator(MappingManagerImpl.
+ getPropagationMappingItems(provision).iterator(),
linkingMappingItems.iterator())));
for (MappingItem item : linkingMappingItems) {
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationReporter.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationReporter.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationReporter.java
index 55c4a0b..635c015 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationReporter.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/DefaultPropagationReporter.java
@@ -28,7 +28,7 @@ import org.apache.syncope.common.lib.to.PropagationStatus;
import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
-import org.apache.syncope.core.misc.utils.ConnObjectUtils;
+import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils;
import org.identityconnectors.framework.common.objects.ConnectorObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java
index 9a7214c..6aa076e 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java
@@ -30,7 +30,7 @@ import org.apache.syncope.core.persistence.api.dao.UserDAO;
import org.apache.syncope.core.persistence.api.entity.group.Group;
import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.misc.jexl.JexlUtils;
+import org.apache.syncope.core.provisioning.java.jexl.JexlUtils;
import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
import org.apache.syncope.core.persistence.api.entity.resource.Provision;
import org.identityconnectors.framework.common.objects.Attribute;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java
index 5ea6616..15ddb30 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PriorityPropagationTaskExecutor.java
@@ -36,7 +36,7 @@ import javax.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.Predicate;
import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
-import org.apache.syncope.core.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
import org.apache.syncope.core.provisioning.api.propagation.PropagationException;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
index f816228..5f66a2f 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationManagerImpl.java
@@ -43,9 +43,9 @@ import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
import org.apache.syncope.core.provisioning.api.WorkflowResult;
import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor;
-import org.apache.syncope.core.misc.utils.ConnObjectUtils;
-import org.apache.syncope.core.misc.utils.MappingUtils;
-import org.apache.syncope.core.misc.jexl.JexlUtils;
+import org.apache.syncope.core.provisioning.java.utils.ConnObjectUtils;
+import org.apache.syncope.core.provisioning.java.MappingManagerImpl;
+import org.apache.syncope.core.provisioning.java.jexl.JexlUtils;
import org.apache.syncope.core.persistence.api.dao.AnyDAO;
import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
@@ -58,6 +58,7 @@ import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
import org.apache.syncope.core.persistence.api.entity.resource.Provision;
import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.provisioning.api.MappingManager;
import org.identityconnectors.framework.common.objects.Attribute;
import org.identityconnectors.framework.common.objects.AttributeBuilder;
import org.identityconnectors.framework.common.objects.AttributeUtil;
@@ -108,7 +109,7 @@ public class PropagationManagerImpl implements PropagationManager {
protected ConnObjectUtils connObjectUtils;
@Autowired
- protected MappingUtils mappingUtils;
+ protected MappingManager mappingManager;
@Autowired
protected AnyUtilsFactory anyUtilsFactory;
@@ -367,7 +368,7 @@ public class PropagationManagerImpl implements PropagationManager {
Provision provision = resource == null ? null : resource.getProvision(any.getType());
List<MappingItem> mappingItems = provision == null
? Collections.<MappingItem>emptyList()
- : MappingUtils.getPropagationMappingItems(provision);
+ : MappingManagerImpl.getPropagationMappingItems(provision);
if (resource == null) {
LOG.error("Invalid resource name specified: {}, ignoring...", entry.getKey());
@@ -391,7 +392,7 @@ public class PropagationManagerImpl implements PropagationManager {
task.setOldConnObjectKey(propByRes.getOldConnObjectKey(resource.getKey()));
Pair<String, Set<Attribute>> preparedAttrs =
- mappingUtils.prepareAttrs(any, password, changePwd, enable, provision);
+ mappingManager.prepareAttrs(any, password, changePwd, enable, provision);
task.setConnObjectKey(preparedAttrs.getKey());
// Check if any of mandatory attributes (in the mapping) is missing or not received any value:
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationTaskCallableImpl.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationTaskCallableImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationTaskCallableImpl.java
index 4e6b875..1c0aa9b 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationTaskCallableImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/PropagationTaskCallableImpl.java
@@ -19,8 +19,8 @@
package org.apache.syncope.core.provisioning.java.propagation;
import java.util.Collection;
-import org.apache.syncope.core.misc.security.AuthContextUtils;
-import org.apache.syncope.core.misc.security.SyncopeAuthenticationDetails;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.SyncopeAuthenticationDetails;
import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter;
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJobDelegate.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJobDelegate.java
deleted file mode 100644
index d6f4c15..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractProvisioningJobDelegate.java
+++ /dev/null
@@ -1,434 +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.provisioning.java.sync;
-
-import java.lang.reflect.ParameterizedType;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import javax.annotation.Resource;
-import org.apache.syncope.common.lib.types.TraceLevel;
-import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
-import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
-import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
-import org.apache.syncope.core.persistence.api.entity.AnyType;
-import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
-import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
-import org.apache.syncope.core.provisioning.api.Connector;
-import org.apache.syncope.core.provisioning.api.ConnectorFactory;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningReport;
-import org.apache.syncope.core.provisioning.java.job.AbstractSchedTaskJobDelegate;
-import org.apache.syncope.core.provisioning.java.job.TaskJob;
-import org.quartz.JobExecutionException;
-import org.springframework.beans.factory.annotation.Autowired;
-
-public abstract class AbstractProvisioningJobDelegate<T extends ProvisioningTask>
- extends AbstractSchedTaskJobDelegate {
-
- @Resource(name = "adminUser")
- protected String adminUser;
-
- /**
- * ConnInstance loader.
- */
- @Autowired
- protected ConnectorFactory connFactory;
-
- @Autowired
- protected AnyTypeDAO anyTypeDAO;
-
- /**
- * Resource DAO.
- */
- @Autowired
- protected ExternalResourceDAO resourceDAO;
-
- /**
- * Policy DAO.
- */
- @Autowired
- protected PolicyDAO policyDAO;
-
- /**
- * Create a textual report of the synchronization, based on the trace level.
- *
- * @param provResults Sync results
- * @param syncTraceLevel Sync trace level
- * @param dryRun dry run?
- * @return report as string
- */
- protected String createReport(final Collection<ProvisioningReport> provResults, final TraceLevel syncTraceLevel,
- final boolean dryRun) {
-
- if (syncTraceLevel == TraceLevel.NONE) {
- return null;
- }
-
- StringBuilder report = new StringBuilder();
-
- if (dryRun) {
- report.append("==>Dry run only, no modifications were made<==\n\n");
- }
-
- List<ProvisioningReport> uSuccCreate = new ArrayList<>();
- List<ProvisioningReport> uFailCreate = new ArrayList<>();
- List<ProvisioningReport> uSuccUpdate = new ArrayList<>();
- List<ProvisioningReport> uFailUpdate = new ArrayList<>();
- List<ProvisioningReport> uSuccDelete = new ArrayList<>();
- List<ProvisioningReport> uFailDelete = new ArrayList<>();
- List<ProvisioningReport> uSuccNone = new ArrayList<>();
- List<ProvisioningReport> uIgnore = new ArrayList<>();
- List<ProvisioningReport> gSuccCreate = new ArrayList<>();
- List<ProvisioningReport> gFailCreate = new ArrayList<>();
- List<ProvisioningReport> gSuccUpdate = new ArrayList<>();
- List<ProvisioningReport> gFailUpdate = new ArrayList<>();
- List<ProvisioningReport> gSuccDelete = new ArrayList<>();
- List<ProvisioningReport> gFailDelete = new ArrayList<>();
- List<ProvisioningReport> gSuccNone = new ArrayList<>();
- List<ProvisioningReport> gIgnore = new ArrayList<>();
- List<ProvisioningReport> aSuccCreate = new ArrayList<>();
- List<ProvisioningReport> aFailCreate = new ArrayList<>();
- List<ProvisioningReport> aSuccUpdate = new ArrayList<>();
- List<ProvisioningReport> aFailUpdate = new ArrayList<>();
- List<ProvisioningReport> aSuccDelete = new ArrayList<>();
- List<ProvisioningReport> aFailDelete = new ArrayList<>();
- List<ProvisioningReport> aSuccNone = new ArrayList<>();
- List<ProvisioningReport> aIgnore = new ArrayList<>();
-
- for (ProvisioningReport provResult : provResults) {
- AnyType anyType = anyTypeDAO.find(provResult.getAnyType());
-
- switch (provResult.getStatus()) {
- case SUCCESS:
- switch (provResult.getOperation()) {
- case CREATE:
- switch (anyType.getKind()) {
- case USER:
- uSuccCreate.add(provResult);
- break;
-
- case GROUP:
- gSuccCreate.add(provResult);
- break;
-
- case ANY_OBJECT:
- default:
- aSuccCreate.add(provResult);
- }
- break;
-
- case UPDATE:
- switch (anyType.getKind()) {
- case USER:
- uSuccUpdate.add(provResult);
- break;
-
- case GROUP:
- gSuccUpdate.add(provResult);
- break;
-
- case ANY_OBJECT:
- default:
- aSuccUpdate.add(provResult);
- }
- break;
-
- case DELETE:
- switch (anyType.getKind()) {
- case USER:
- uSuccDelete.add(provResult);
- break;
-
- case GROUP:
- gSuccDelete.add(provResult);
- break;
-
- case ANY_OBJECT:
- default:
- aSuccDelete.add(provResult);
- }
- break;
-
- case NONE:
- switch (anyType.getKind()) {
- case USER:
- uSuccNone.add(provResult);
- break;
-
- case GROUP:
- gSuccNone.add(provResult);
- break;
-
- case ANY_OBJECT:
- default:
- aSuccNone.add(provResult);
- }
- break;
-
- default:
- }
- break;
-
- case FAILURE:
- switch (provResult.getOperation()) {
- case CREATE:
- switch (anyType.getKind()) {
- case USER:
- uFailCreate.add(provResult);
- break;
-
- case GROUP:
- gFailCreate.add(provResult);
- break;
-
- case ANY_OBJECT:
- default:
- aFailCreate.add(provResult);
- }
- break;
-
- case UPDATE:
- switch (anyType.getKind()) {
- case USER:
- uFailUpdate.add(provResult);
- break;
-
- case GROUP:
- gFailUpdate.add(provResult);
- break;
-
- case ANY_OBJECT:
- default:
- aFailUpdate.add(provResult);
- }
- break;
-
- case DELETE:
- switch (anyType.getKind()) {
- case USER:
- uFailDelete.add(provResult);
- break;
-
- case GROUP:
- gFailDelete.add(provResult);
- break;
-
- case ANY_OBJECT:
- default:
- aFailDelete.add(provResult);
- }
- break;
-
- default:
- }
- break;
-
- case IGNORE:
- switch (anyType.getKind()) {
- case USER:
- uIgnore.add(provResult);
- break;
-
- case GROUP:
- gIgnore.add(provResult);
- break;
-
- case ANY_OBJECT:
- default:
- aIgnore.add(provResult);
- }
- break;
-
- default:
- }
- }
-
- // Summary, also to be included for FAILURE and ALL, so create it anyway.
- report.append("Users ").
- append("[created/failures]: ").append(uSuccCreate.size()).append('/').append(uFailCreate.size()).
- append(' ').
- append("[updated/failures]: ").append(uSuccUpdate.size()).append('/').append(uFailUpdate.size()).
- append(' ').
- append("[deleted/failures]: ").append(uSuccDelete.size()).append('/').append(uFailDelete.size()).
- append(' ').
- append("[no operation/ignored]: ").append(uSuccNone.size()).append('/').append(uIgnore.size()).
- append('\n');
- report.append("Groups ").
- append("[created/failures]: ").append(gSuccCreate.size()).append('/').append(gFailCreate.size()).
- append(' ').
- append("[updated/failures]: ").append(gSuccUpdate.size()).append('/').append(gFailUpdate.size()).
- append(' ').
- append("[deleted/failures]: ").append(gSuccDelete.size()).append('/').append(gFailDelete.size()).
- append(' ').
- append("[no operation/ignored]: ").append(gSuccNone.size()).append('/').append(gIgnore.size()).
- append('\n');
- report.append("Any objects ").
- append("[created/failures]: ").append(aSuccCreate.size()).append('/').append(aFailCreate.size()).
- append(' ').
- append("[updated/failures]: ").append(aSuccUpdate.size()).append('/').append(aFailUpdate.size()).
- append(' ').
- append("[deleted/failures]: ").append(aSuccDelete.size()).append('/').append(aFailDelete.size()).
- append(' ').
- append("[no operation/ignored]: ").append(aSuccNone.size()).append('/').append(aIgnore.size());
-
- // Failures
- if (syncTraceLevel == TraceLevel.FAILURES || syncTraceLevel == TraceLevel.ALL) {
- if (!uFailCreate.isEmpty()) {
- report.append("\n\nUsers failed to create: ");
- report.append(ProvisioningReport.produceReport(uFailCreate, syncTraceLevel));
- }
- if (!uFailUpdate.isEmpty()) {
- report.append("\nUsers failed to update: ");
- report.append(ProvisioningReport.produceReport(uFailUpdate, syncTraceLevel));
- }
- if (!uFailDelete.isEmpty()) {
- report.append("\nUsers failed to delete: ");
- report.append(ProvisioningReport.produceReport(uFailDelete, syncTraceLevel));
- }
-
- if (!gFailCreate.isEmpty()) {
- report.append("\n\nGroups failed to create: ");
- report.append(ProvisioningReport.produceReport(gFailCreate, syncTraceLevel));
- }
- if (!gFailUpdate.isEmpty()) {
- report.append("\nGroups failed to update: ");
- report.append(ProvisioningReport.produceReport(gFailUpdate, syncTraceLevel));
- }
- if (!gFailDelete.isEmpty()) {
- report.append("\nGroups failed to delete: ");
- report.append(ProvisioningReport.produceReport(gFailDelete, syncTraceLevel));
- }
-
- if (!aFailCreate.isEmpty()) {
- report.append("\nAny objects failed to create: ");
- report.append(ProvisioningReport.produceReport(aFailCreate, syncTraceLevel));
- }
- if (!aFailUpdate.isEmpty()) {
- report.append("\nAny objects failed to update: ");
- report.append(ProvisioningReport.produceReport(aFailUpdate, syncTraceLevel));
- }
- if (!aFailDelete.isEmpty()) {
- report.append("\nAny objects failed to delete: ");
- report.append(ProvisioningReport.produceReport(aFailDelete, syncTraceLevel));
- }
- }
-
- // Succeeded, only if on 'ALL' level
- if (syncTraceLevel == TraceLevel.ALL) {
- report.append("\n\nUsers created:\n").
- append(ProvisioningReport.produceReport(uSuccCreate, syncTraceLevel)).
- append("\nUsers updated:\n").
- append(ProvisioningReport.produceReport(uSuccUpdate, syncTraceLevel)).
- append("\nUsers deleted:\n").
- append(ProvisioningReport.produceReport(uSuccDelete, syncTraceLevel)).
- append("\nUsers no operation:\n").
- append(ProvisioningReport.produceReport(uSuccNone, syncTraceLevel)).
- append("\nUsers ignored:\n").
- append(ProvisioningReport.produceReport(uIgnore, syncTraceLevel));
- report.append("\n\nGroups created:\n").
- append(ProvisioningReport.produceReport(gSuccCreate, syncTraceLevel)).
- append("\nGroups updated:\n").
- append(ProvisioningReport.produceReport(gSuccUpdate, syncTraceLevel)).
- append("\nGroups deleted:\n").
- append(ProvisioningReport.produceReport(gSuccDelete, syncTraceLevel)).
- append("\nGroups no operation:\n").
- append(ProvisioningReport.produceReport(gSuccNone, syncTraceLevel)).
- append("\nGroups ignored:\n").
- append(ProvisioningReport.produceReport(gSuccNone, syncTraceLevel));
- report.append("\n\nAny objects created:\n").
- append(ProvisioningReport.produceReport(aSuccCreate, syncTraceLevel)).
- append("\nAny objects updated:\n").
- append(ProvisioningReport.produceReport(aSuccUpdate, syncTraceLevel)).
- append("\nAny objects deleted:\n").
- append(ProvisioningReport.produceReport(aSuccDelete, syncTraceLevel)).
- append("\nAny objects no operation:\n").
- append(ProvisioningReport.produceReport(aSuccNone, syncTraceLevel)).
- append("\nAny objects ignored:\n").
- append(ProvisioningReport.produceReport(aSuccNone, syncTraceLevel));
- }
-
- return report.toString();
- }
-
- @Override
- protected String doExecute(final boolean dryRun) throws JobExecutionException {
- try {
- Class<T> clazz = getTaskClassReference();
- if (!clazz.isAssignableFrom(task.getClass())) {
- throw new JobExecutionException("Task " + task.getKey() + " isn't a ProvisioningTask");
- }
-
- T provisioningTask = clazz.cast(task);
-
- Connector connector;
- try {
- connector = connFactory.getConnector(provisioningTask.getResource());
- } catch (Exception e) {
- String msg = String.format("Connector instance bean for resource %s and connInstance %s not found",
- provisioningTask.getResource(), provisioningTask.getResource().getConnector());
- throw new JobExecutionException(msg, e);
- }
-
- boolean noMapping = true;
- for (Provision provision : provisioningTask.getResource().getProvisions()) {
- Mapping mapping = provision.getMapping();
- if (mapping != null) {
- noMapping = false;
- if (mapping.getConnObjectKeyItem() == null) {
- throw new JobExecutionException(
- "Invalid ConnObjectKey mapping for provision " + provision);
- }
- }
- }
- if (noMapping) {
- return "No mapping configured for both users and groups: aborting...";
- }
-
- return doExecuteProvisioning(
- provisioningTask,
- connector,
- dryRun);
- } catch (Throwable t) {
- LOG.error("While executing provisioning job {}", getClass().getName(), t);
- throw t;
- }
- }
-
- protected abstract String doExecuteProvisioning(
- final T task,
- final Connector connector,
- final boolean dryRun) throws JobExecutionException;
-
- @Override
- protected boolean hasToBeRegistered(final TaskExec execution) {
- final ProvisioningTask provTask = (ProvisioningTask) task;
-
- // True if either failed and failures have to be registered, or if ALL has to be registered.
- return (TaskJob.Status.valueOf(execution.getStatus()) == TaskJob.Status.FAILURE
- && provTask.getResource().getSyncTraceLevel().ordinal() >= TraceLevel.FAILURES.ordinal())
- || provTask.getResource().getSyncTraceLevel().ordinal() >= TraceLevel.SUMMARY.ordinal();
- }
-
- @SuppressWarnings("unchecked")
- private Class<T> getTaskClassReference() {
- return (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/28569df5/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java
deleted file mode 100644
index f88982f..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/sync/AbstractPushResultHandler.java
+++ /dev/null
@@ -1,434 +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.provisioning.java.sync;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import org.apache.commons.collections4.IteratorUtils;
-import org.apache.commons.lang3.exception.ExceptionUtils;
-import org.apache.syncope.common.lib.patch.AnyPatch;
-import org.apache.syncope.common.lib.patch.StringPatchItem;
-import org.apache.syncope.common.lib.to.AnyTO;
-import org.apache.syncope.common.lib.types.AuditElements;
-import org.apache.syncope.common.lib.types.AuditElements.Result;
-import org.apache.syncope.common.lib.types.MatchingRule;
-import org.apache.syncope.common.lib.types.PatchOperation;
-import org.apache.syncope.common.lib.types.PropagationByResource;
-import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.common.lib.types.UnmatchingRule;
-import org.apache.syncope.core.persistence.api.entity.task.PushTask;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.provisioning.api.sync.ProvisioningReport;
-import org.apache.syncope.core.provisioning.api.sync.PushActions;
-import org.apache.syncope.core.misc.utils.MappingUtils;
-import org.apache.syncope.core.persistence.api.entity.Any;
-import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
-import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
-import org.apache.syncope.core.persistence.api.entity.resource.Provision;
-import org.apache.syncope.core.provisioning.api.TimeoutException;
-import org.apache.syncope.core.provisioning.api.sync.IgnoreProvisionException;
-import org.apache.syncope.core.provisioning.api.sync.SyncopePushResultHandler;
-import org.identityconnectors.framework.common.objects.ConnectorObject;
-import org.identityconnectors.framework.common.objects.ObjectClass;
-import org.identityconnectors.framework.common.objects.Uid;
-import org.quartz.JobExecutionException;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Propagation;
-import org.springframework.transaction.annotation.Transactional;
-
-public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHandler<PushTask, PushActions>
- implements SyncopePushResultHandler {
-
- @Autowired
- protected MappingUtils mappingUtils;
-
- protected abstract String getName(Any<?> any);
-
- protected void deprovision(final Any<?> any) {
- AnyTO before = getAnyTO(any.getKey());
-
- List<String> noPropResources = new ArrayList<>(before.getResources());
- noPropResources.remove(profile.getTask().getResource().getKey());
-
- taskExecutor.execute(propagationManager.getDeleteTasks(
- any.getType().getKind(),
- any.getKey(),
- null,
- noPropResources));
- }
-
- protected void provision(final Any<?> any, final Boolean enabled) {
- AnyTO before = getAnyTO(any.getKey());
-
- List<String> noPropResources = new ArrayList<>(before.getResources());
- noPropResources.remove(profile.getTask().getResource().getKey());
-
- PropagationByResource propByRes = new PropagationByResource();
- propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
-
- taskExecutor.execute(propagationManager.getCreateTasks(
- any.getType().getKind(),
- any.getKey(),
- propByRes,
- before.getVirAttrs(),
- noPropResources));
- }
-
- @SuppressWarnings("unchecked")
- protected void link(final Any<?> any, final Boolean unlink) {
- AnyPatch patch = newPatch(any.getKey());
- patch.getResources().add(new StringPatchItem.Builder().
- operation(unlink ? PatchOperation.DELETE : PatchOperation.ADD_REPLACE).
- value(profile.getTask().getResource().getKey()).build());
-
- update(patch);
- }
-
- @SuppressWarnings("unchecked")
- protected void unassign(final Any<?> any) {
- AnyPatch patch = newPatch(any.getKey());
- patch.getResources().add(new StringPatchItem.Builder().
- operation(PatchOperation.DELETE).
- value(profile.getTask().getResource().getKey()).build());
-
- update(patch);
-
- deprovision(any);
- }
-
- protected void assign(final Any<?> any, final Boolean enabled) {
- AnyPatch patch = newPatch(any.getKey());
- patch.getResources().add(new StringPatchItem.Builder().
- operation(PatchOperation.ADD_REPLACE).
- value(profile.getTask().getResource().getKey()).build());
-
- update(patch);
-
- provision(any, enabled);
- }
-
- protected ConnectorObject getRemoteObject(final String connObjectKey, final ObjectClass objectClass) {
- ConnectorObject obj = null;
- try {
- Uid uid = new Uid(connObjectKey);
-
- obj = profile.getConnector().getObject(
- objectClass,
- uid,
- MappingUtils.buildOperationOptions(IteratorUtils.<MappingItem>emptyIterator()));
- } catch (TimeoutException toe) {
- LOG.debug("Request timeout", toe);
- throw toe;
- } catch (RuntimeException ignore) {
- LOG.debug("While resolving {}", connObjectKey, ignore);
- }
-
- return obj;
- }
-
- @Transactional(propagation = Propagation.REQUIRES_NEW)
- @Override
- public boolean handle(final long anyKey) {
- Any<?> any = null;
- try {
- any = getAny(anyKey);
- doHandle(any);
- return true;
- } catch (IgnoreProvisionException e) {
- ProvisioningReport result = new ProvisioningReport();
- result.setOperation(ResourceOperation.NONE);
- result.setAnyType(any == null ? null : any.getType().getKey());
- result.setStatus(ProvisioningReport.Status.IGNORE);
- result.setKey(anyKey);
- profile.getResults().add(result);
-
- LOG.warn("Ignoring during push", e);
- return true;
- } catch (JobExecutionException e) {
- LOG.error("Push failed", e);
- return false;
- }
- }
-
- protected final void doHandle(final Any<?> any) throws JobExecutionException {
- AnyUtils anyUtils = anyUtilsFactory.getInstance(any);
-
- ProvisioningReport result = new ProvisioningReport();
- profile.getResults().add(result);
-
- result.setKey(any.getKey());
- result.setAnyType(any.getType().getKey());
- result.setName(getName(any));
-
- Boolean enabled = any instanceof User && profile.getTask().isSyncStatus()
- ? ((User) any).isSuspended() ? Boolean.FALSE : Boolean.TRUE
- : null;
-
- LOG.debug("Propagating {} with key {} towards {}",
- anyUtils.getAnyTypeKind(), any.getKey(), profile.getTask().getResource());
-
- Object output = null;
- Result resultStatus = null;
- String operation = null;
-
- // Try to read remote object BEFORE any actual operation
- Provision provision = profile.getTask().getResource().getProvision(any.getType());
- String connObjecKey = mappingUtils.getConnObjectKeyValue(any, provision);
-
- ConnectorObject beforeObj = getRemoteObject(connObjecKey, provision.getObjectClass());
-
- Boolean status = profile.getTask().isSyncStatus() ? enabled : null;
-
- if (profile.isDryRun()) {
- if (beforeObj == null) {
- result.setOperation(getResourceOperation(profile.getTask().getUnmatchingRule()));
- } else {
- result.setOperation(getResourceOperation(profile.getTask().getMatchingRule()));
- }
- result.setStatus(ProvisioningReport.Status.SUCCESS);
- } else {
- try {
- if (beforeObj == null) {
- operation = UnmatchingRule.toEventName(profile.getTask().getUnmatchingRule());
- result.setOperation(getResourceOperation(profile.getTask().getUnmatchingRule()));
-
- switch (profile.getTask().getUnmatchingRule()) {
- case ASSIGN:
- for (PushActions action : profile.getActions()) {
- action.beforeAssign(this.getProfile(), any);
- }
-
- if (!profile.getTask().isPerformCreate()) {
- LOG.debug("PushTask not configured for create");
- } else {
- assign(any, status);
- }
-
- break;
-
- case PROVISION:
- for (PushActions action : profile.getActions()) {
- action.beforeProvision(this.getProfile(), any);
- }
-
- if (!profile.getTask().isPerformCreate()) {
- LOG.debug("PushTask not configured for create");
- } else {
- provision(any, status);
- }
-
- break;
-
- case UNLINK:
- for (PushActions action : profile.getActions()) {
- action.beforeUnlink(this.getProfile(), any);
- }
-
- if (!profile.getTask().isPerformUpdate()) {
- LOG.debug("PushTask not configured for update");
- } else {
- link(any, true);
- }
-
- break;
-
- case IGNORE:
- LOG.debug("Ignored any: {}", any);
- break;
- default:
- // do nothing
- }
- } else {
- operation = MatchingRule.toEventName(profile.getTask().getMatchingRule());
- result.setOperation(getResourceOperation(profile.getTask().getMatchingRule()));
-
- switch (profile.getTask().getMatchingRule()) {
- case UPDATE:
- for (PushActions action : profile.getActions()) {
- action.beforeUpdate(this.getProfile(), any);
- }
- if (!profile.getTask().isPerformUpdate()) {
- LOG.debug("PushTask not configured for update");
- } else {
- update(any, status);
- }
-
- break;
-
- case DEPROVISION:
- for (PushActions action : profile.getActions()) {
- action.beforeDeprovision(this.getProfile(), any);
- }
-
- if (!profile.getTask().isPerformDelete()) {
- LOG.debug("PushTask not configured for delete");
- } else {
- deprovision(any);
- }
-
- break;
-
- case UNASSIGN:
- for (PushActions action : profile.getActions()) {
- action.beforeUnassign(this.getProfile(), any);
- }
-
- if (!profile.getTask().isPerformDelete()) {
- LOG.debug("PushTask not configured for delete");
- } else {
- unassign(any);
- }
-
- break;
-
- case LINK:
- for (PushActions action : profile.getActions()) {
- action.beforeLink(this.getProfile(), any);
- }
-
- if (!profile.getTask().isPerformUpdate()) {
- LOG.debug("PushTask not configured for update");
- } else {
- link(any, false);
- }
-
- break;
-
- case UNLINK:
- for (PushActions action : profile.getActions()) {
- action.beforeUnlink(this.getProfile(), any);
- }
-
- if (!profile.getTask().isPerformUpdate()) {
- LOG.debug("PushTask not configured for update");
- } else {
- link(any, true);
- }
-
- break;
-
- case IGNORE:
- LOG.debug("Ignored any: {}", any);
- break;
- default:
- // do nothing
- }
- }
-
- for (PushActions action : profile.getActions()) {
- action.after(this.getProfile(), any, result);
- }
-
- result.setStatus(ProvisioningReport.Status.SUCCESS);
- resultStatus = AuditElements.Result.SUCCESS;
- output = getRemoteObject(connObjecKey, provision.getObjectClass());
- } catch (IgnoreProvisionException e) {
- throw e;
- } catch (Exception e) {
- result.setStatus(ProvisioningReport.Status.FAILURE);
- result.setMessage(ExceptionUtils.getRootCauseMessage(e));
- resultStatus = AuditElements.Result.FAILURE;
- output = e;
-
- LOG.warn("Error pushing {} towards {}", any, profile.getTask().getResource(), e);
-
- for (PushActions action : profile.getActions()) {
- action.onError(this.getProfile(), any, result, e);
- }
-
- throw new JobExecutionException(e);
- } finally {
- notificationManager.createTasks(AuditElements.EventCategoryType.PUSH,
- any.getType().getKind().name().toLowerCase(),
- profile.getTask().getResource().getKey(),
- operation,
- resultStatus,
- beforeObj,
- output,
- any);
- auditManager.audit(AuditElements.EventCategoryType.PUSH,
- any.getType().getKind().name().toLowerCase(),
- profile.getTask().getResource().getKey(),
- operation,
- resultStatus,
- connObjectUtils.getConnObjectTO(beforeObj),
- output instanceof ConnectorObject
- ? connObjectUtils.getConnObjectTO((ConnectorObject) output) : output,
- any);
- }
- }
- }
-
- private ResourceOperation getResourceOperation(final UnmatchingRule rule) {
- switch (rule) {
- case ASSIGN:
- case PROVISION:
- return ResourceOperation.CREATE;
- default:
- return ResourceOperation.NONE;
- }
- }
-
- private ResourceOperation getResourceOperation(final MatchingRule rule) {
- switch (rule) {
- case UPDATE:
- return ResourceOperation.UPDATE;
- case DEPROVISION:
- case UNASSIGN:
- return ResourceOperation.DELETE;
- default:
- return ResourceOperation.NONE;
- }
- }
-
- protected Any<?> update(final Any<?> any, final Boolean enabled) {
- boolean changepwd;
- Collection<String> resourceNames;
- if (any instanceof User) {
- changepwd = true;
- resourceNames = userDAO.findAllResourceNames((User) any);
- } else if (any instanceof AnyObject) {
- changepwd = false;
- resourceNames = anyObjectDAO.findAllResourceNames((AnyObject) any);
- } else {
- changepwd = false;
- resourceNames = ((Group) any).getResourceNames();
- }
-
- List<String> noPropResources = new ArrayList<>(resourceNames);
- noPropResources.remove(profile.getTask().getResource().getKey());
-
- PropagationByResource propByRes = new PropagationByResource();
- propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
-
- taskExecutor.execute(propagationManager.getUpdateTasks(
- any.getType().getKind(),
- any.getKey(),
- changepwd,
- null,
- propByRes,
- null,
- noPropResources));
-
- return getAny(any.getKey());
- }
-}