This is an automated email from the ASF dual-hosted git repository. ilgrosso pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/syncope.git
commit 7ed3a9c2232faf78e1b5f2a2f323d051f92aa0ba Author: Francesco Chicchiriccò <ilgro...@apache.org> AuthorDate: Fri Jun 11 14:22:42 2021 +0200 Futher enhancements for extendability --- .../core/provisioning/api/ConnectorFactory.java | 14 +++++++-- .../provisioning/java/ConnectorFacadeProxy.java | 16 ++++------- .../core/provisioning/java/ConnectorManager.java | 33 +++++++++++++--------- .../pushpull/AbstractProvisioningJobDelegate.java | 22 +++++++++------ 4 files changed, 50 insertions(+), 35 deletions(-) diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ConnectorFactory.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ConnectorFactory.java index 2494df3..815a847 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ConnectorFactory.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/ConnectorFactory.java @@ -55,13 +55,21 @@ public interface ConnectorFactory { Connector createConnector(ConnInstance connInstance); /** - * Get existing connector for the given resource. + * Get existing connector bean for the given resource or create if not found. * - * @param resource the resource. - * @return live connector bran for given resource + * @param resource the resource + * @return live connector bean for given resource */ Connector getConnector(ExternalResource resource); + /* + * Get existing connector bean for the given resource if found. + * + * @param resource the resource. + * @return live connector bean for given resource + */ + Optional<Connector> readConnector(ExternalResource resource); + /** * Load connectors for all existing resources. * diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java index ad89d8f..8a1f7d1 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorFacadeProxy.java @@ -33,6 +33,7 @@ import org.apache.syncope.core.provisioning.api.Connector; import org.apache.syncope.core.provisioning.api.TimeoutException; import org.apache.syncope.core.provisioning.api.pushpull.ReconFilterBuilder; import org.apache.syncope.core.spring.ApplicationContextProvider; +import org.identityconnectors.common.CollectionUtil; import org.identityconnectors.common.security.GuardedByteArray; import org.identityconnectors.common.security.GuardedString; import org.identityconnectors.framework.api.APIConfiguration; @@ -54,10 +55,7 @@ import org.identityconnectors.framework.common.objects.filter.Filter; import org.identityconnectors.framework.spi.SearchResultsHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.transaction.annotation.Transactional; import org.springframework.util.ClassUtils; -import org.springframework.util.CollectionUtils; public class ConnectorFacadeProxy implements Connector { @@ -75,20 +73,21 @@ public class ConnectorFacadeProxy implements Connector { */ private final ConnInstance connInstance; - @Autowired - private AsyncConnectorFacade asyncFacade; + private final AsyncConnectorFacade asyncFacade; /** * Use the passed connector instance to build a ConnectorFacade that will be used to make all wrapped calls. * * @param connInstance the connector instance + * @param asyncFacade the async connectot facade * @see ConnectorInfo * @see APIConfiguration * @see ConfigurationProperties * @see ConnectorFacade */ - public ConnectorFacadeProxy(final ConnInstance connInstance) { + public ConnectorFacadeProxy(final ConnInstance connInstance, final AsyncConnectorFacade asyncFacade) { this.connInstance = connInstance; + this.asyncFacade = asyncFacade; ConnIdBundleManager connIdBundleManager = ApplicationContextProvider.getBeanFactory().getBean(ConnIdBundleManager.class); @@ -105,7 +104,7 @@ public class ConnectorFacadeProxy implements Connector { // set connector configuration according to conninstance's ConfigurationProperties properties = apiConfig.getConfigurationProperties(); connInstance.getConf().stream(). - filter(property -> !CollectionUtils.isEmpty(property.getValues())). + filter(property -> !CollectionUtil.isEmpty(property.getValues())). forEach(property -> properties.setPropertyValue( property.getSchema().getName(), getPropertyValue(property.getSchema().getType(), property.getValues()))); @@ -257,7 +256,6 @@ public class ConnectorFacadeProxy implements Connector { } } - @Transactional @Override public void sync(final ObjectClass objectClass, final SyncToken token, final SyncResultsHandler handler, final OperationOptions options) { @@ -298,7 +296,6 @@ public class ConnectorFacadeProxy implements Connector { return result; } - @Transactional @Override public void fullReconciliation( final ObjectClass objectClass, @@ -308,7 +305,6 @@ public class ConnectorFacadeProxy implements Connector { Connector.super.fullReconciliation(objectClass, handler, options); } - @Transactional @Override public void filteredReconciliation( final ObjectClass objectClass, diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java index 0f2bce3..1a7d1be 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ConnectorManager.java @@ -68,6 +68,9 @@ public class ConnectorManager implements ConnectorRegistry, ConnectorFactory { @Autowired private ConnInstanceDataBinder connInstanceDataBinder; + @Autowired + private AsyncConnectorFacade asyncFacade; + private EntityFactory entityFactory; private static String getBeanName(final ExternalResource resource) { @@ -76,13 +79,18 @@ public class ConnectorManager implements ConnectorRegistry, ConnectorFactory { } @Override + public Optional<Connector> readConnector(final ExternalResource resource) { + return Optional.ofNullable((Connector) ApplicationContextProvider.getBeanFactory(). + getSingleton(getBeanName(resource))); + } + + @Override public Connector getConnector(final ExternalResource resource) { // Try to re-create connector bean from underlying resource (useful for managing failover scenarios) - if (!ApplicationContextProvider.getBeanFactory().containsSingleton(getBeanName(resource))) { + return readConnector(resource).orElseGet(() -> { registerConnector(resource); - } - - return ApplicationContextProvider.getBeanFactory().getBean(getBeanName(resource), Connector.class); + return (Connector) ApplicationContextProvider.getBeanFactory().getSingleton(getBeanName(resource)); + }); } @Override @@ -148,14 +156,17 @@ public class ConnectorManager implements ConnectorRegistry, ConnectorFactory { @Override public Connector createConnector(final ConnInstance connInstance) { - Connector connector = new ConnectorFacadeProxy(connInstance); - ApplicationContextProvider.getBeanFactory().autowireBean(connector); - - return connector; + return new ConnectorFacadeProxy(connInstance, asyncFacade); } @Override public void registerConnector(final ExternalResource resource) { + String beanName = getBeanName(resource); + + if (ApplicationContextProvider.getBeanFactory().containsSingleton(beanName)) { + unregisterConnector(beanName); + } + ConnInstance connInstance = buildConnInstanceOverride( connInstanceDataBinder.getConnInstanceTO(resource.getConnector()), resource.getConfOverride(), @@ -163,12 +174,6 @@ public class ConnectorManager implements ConnectorRegistry, ConnectorFactory { Connector connector = createConnector(connInstance); LOG.debug("Connector to be registered: {}", connector); - String beanName = getBeanName(resource); - - if (ApplicationContextProvider.getBeanFactory().containsSingleton(beanName)) { - unregisterConnector(beanName); - } - ApplicationContextProvider.getBeanFactory().registerSingleton(beanName, connector); LOG.debug("Successfully registered bean {}", beanName); } diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractProvisioningJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractProvisioningJobDelegate.java index 7fec620..5ff17e0 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractProvisioningJobDelegate.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractProvisioningJobDelegate.java @@ -626,6 +626,19 @@ public abstract class AbstractProvisioningJobDelegate<T extends ProvisioningTask return report.toString(); } + protected Connector getConnector(final T provisioningTask) throws JobExecutionException { + 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); + } + + return connector; + } + @Override protected String doExecute(final boolean dryRun, final String executor, final JobExecutionContext context) throws JobExecutionException { @@ -638,14 +651,7 @@ public abstract class AbstractProvisioningJobDelegate<T extends 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); - } + Connector connector = getConnector(provisioningTask); boolean noMapping = true; for (Provision provision : provisioningTask.getResource().getProvisions()) {