List of usage examples for java.util.concurrent ScheduledExecutorService isTerminated
boolean isTerminated();
From source file:org.alfresco.repo.security.sync.ChainingUserRegistrySynchronizer.java
private void synchronizeInternal(boolean forceUpdate, boolean isFullSync, final boolean splitTxns) { if (ChainingUserRegistrySynchronizer.logger.isDebugEnabled()) { if (forceUpdate) { ChainingUserRegistrySynchronizer.logger.debug("Running a full sync."); } else {//w w w .ja va 2 s . c o m ChainingUserRegistrySynchronizer.logger.debug("Running a differential sync."); } if (allowDeletions) { ChainingUserRegistrySynchronizer.logger.debug("deletions are allowed"); } else { ChainingUserRegistrySynchronizer.logger.debug("deletions are not allowed"); } // Don't proceed with the sync if the repository is read only if (this.transactionService.isReadOnly()) { ChainingUserRegistrySynchronizer.logger .warn("Unable to proceed with user registry synchronization. Repository is read only."); return; } } // Don't proceed with the sync if the repository is read only if (this.transactionService.isReadOnly()) { ChainingUserRegistrySynchronizer.logger .warn("Unable to proceed with user registry synchronization. Repository is read only."); return; } // Create a background executor that will refresh our lock. This means we can request a lock with a relatively // small persistence time and not worry about it lasting after server restarts. Note we use an independent // executor because this is a compound operation that spans accross multiple batch processors. String lockToken = null; TraceableThreadFactory threadFactory = new TraceableThreadFactory(); threadFactory.setNamePrefix("ChainingUserRegistrySynchronizer lock refresh"); threadFactory.setThreadDaemon(true); ScheduledExecutorService lockRefresher = new ScheduledThreadPoolExecutor(1, threadFactory); // Let's ensure all exceptions get logged try { // First, try to obtain a lock to ensure we are the only node trying to run this job try { if (splitTxns) { // If this is an automated sync on startup or scheduled sync, don't even wait around for the lock. // Assume the sync will be completed on another node. lockToken = this.transactionService.getRetryingTransactionHelper() .doInTransaction(new RetryingTransactionCallback<String>() { public String execute() throws Throwable { return ChainingUserRegistrySynchronizer.this.jobLockService.getLock( ChainingUserRegistrySynchronizer.LOCK_QNAME, ChainingUserRegistrySynchronizer.LOCK_TTL, 0, 1); } }, false, splitTxns); } else { // If this is a login-triggered sync, give it a few retries before giving up lockToken = this.jobLockService.getLock(ChainingUserRegistrySynchronizer.LOCK_QNAME, ChainingUserRegistrySynchronizer.LOCK_TTL, 3000, 10); } } catch (LockAcquisitionException e) { // Don't proceed with the sync if it is running on another node ChainingUserRegistrySynchronizer.logger.warn( "User registry synchronization already running in another thread. Synchronize aborted"); return; } // Schedule the lock refresh to run at regular intervals final String token = lockToken; lockRefresher.scheduleAtFixedRate(new Runnable() { public void run() { ChainingUserRegistrySynchronizer.this.transactionService.getRetryingTransactionHelper() .doInTransaction(new RetryingTransactionCallback<Object>() { public Object execute() throws Throwable { ChainingUserRegistrySynchronizer.this.jobLockService.refreshLock(token, ChainingUserRegistrySynchronizer.LOCK_QNAME, ChainingUserRegistrySynchronizer.LOCK_TTL); return null; } }, false, splitTxns); } }, ChainingUserRegistrySynchronizer.LOCK_TTL / 2, ChainingUserRegistrySynchronizer.LOCK_TTL / 2, TimeUnit.MILLISECONDS); Set<String> visitedZoneIds = new TreeSet<String>(); Collection<String> instanceIds = this.applicationContextManager.getInstanceIds(); // Work out the set of all zone IDs in the authentication chain so that we can decide which users / groups // need 're-zoning' Set<String> allZoneIds = new TreeSet<String>(); for (String id : instanceIds) { allZoneIds.add(AuthorityService.ZONE_AUTH_EXT_PREFIX + id); } // Collect the plugins that we can sync : zoneId, plugin Map<String, UserRegistry> plugins = new HashMap<String, UserRegistry>(); for (String id : instanceIds) { UserRegistry plugin; try { ApplicationContext context = this.applicationContextManager.getApplicationContext(id); plugin = (UserRegistry) context.getBean(this.sourceBeanName); } catch (RuntimeException e) { // The bean doesn't exist or this subsystem won't start. The reason would have been logged. Ignore and continue. continue; } if (!(plugin instanceof ActivateableBean) || ((ActivateableBean) plugin).isActive()) { // yes this plugin needs to be synced plugins.put(id, plugin); } } /** * Sync starts here */ notifySyncStart(plugins.keySet()); for (String id : instanceIds) { UserRegistry plugin = plugins.get(id); if (plugin != null) { // If debug is enabled then dump out the contents of the authentication JMX bean if (ChainingUserRegistrySynchronizer.logger.isDebugEnabled()) { mbeanServer = (MBeanServerConnection) getApplicationContext() .getBean("alfrescoMBeanServer"); try { StringBuilder nameBuff = new StringBuilder(200) .append("Alfresco:Type=Configuration,Category=Authentication,id1=managed,id2=") .append(URLDecoder.decode(id, "UTF-8")); ObjectName name = new ObjectName(nameBuff.toString()); if (mbeanServer != null && mbeanServer.isRegistered(name)) { MBeanInfo info = mbeanServer.getMBeanInfo(name); MBeanAttributeInfo[] attributes = info.getAttributes(); ChainingUserRegistrySynchronizer.logger.debug(id + " attributes:"); for (MBeanAttributeInfo attribute : attributes) { Object value = mbeanServer.getAttribute(name, attribute.getName()); ChainingUserRegistrySynchronizer.logger .debug(attribute.getName() + " = " + value); } } } catch (UnsupportedEncodingException e) { if (ChainingUserRegistrySynchronizer.logger.isWarnEnabled()) { ChainingUserRegistrySynchronizer.logger.warn("Exception during logging", e); } } catch (MalformedObjectNameException e) { if (ChainingUserRegistrySynchronizer.logger.isWarnEnabled()) { ChainingUserRegistrySynchronizer.logger.warn("Exception during logging", e); } } catch (InstanceNotFoundException e) { if (ChainingUserRegistrySynchronizer.logger.isWarnEnabled()) { ChainingUserRegistrySynchronizer.logger.warn("Exception during logging", e); } } catch (IntrospectionException e) { if (ChainingUserRegistrySynchronizer.logger.isWarnEnabled()) { ChainingUserRegistrySynchronizer.logger.warn("Exception during logging", e); } } catch (AttributeNotFoundException e) { if (ChainingUserRegistrySynchronizer.logger.isWarnEnabled()) { ChainingUserRegistrySynchronizer.logger.warn("Exception during logging", e); } } catch (ReflectionException e) { if (ChainingUserRegistrySynchronizer.logger.isWarnEnabled()) { ChainingUserRegistrySynchronizer.logger.warn("Exception during logging", e); } } catch (MBeanException e) { if (ChainingUserRegistrySynchronizer.logger.isWarnEnabled()) { ChainingUserRegistrySynchronizer.logger.warn("Exception during logging", e); } } catch (IOException e) { if (ChainingUserRegistrySynchronizer.logger.isWarnEnabled()) { ChainingUserRegistrySynchronizer.logger.warn("Exception during logging", e); } } } // end of debug dump of active JMX bean if (ChainingUserRegistrySynchronizer.logger.isInfoEnabled()) { ChainingUserRegistrySynchronizer.logger .info("Synchronizing users and groups with user registry '" + id + "'"); } if (isFullSync && ChainingUserRegistrySynchronizer.logger.isWarnEnabled()) { ChainingUserRegistrySynchronizer.logger .warn("Full synchronization with user registry '" + id + "'"); if (allowDeletions) { ChainingUserRegistrySynchronizer.logger.warn( "Some users and groups previously created by synchronization with this user registry may be removed."); } else { ChainingUserRegistrySynchronizer.logger.warn( "Deletions are disabled. Users and groups removed from this registry will be logged only and will remain in the repository. Users previously found in a different registry will be moved in the repository rather than recreated."); } } // Work out whether we should do the work in a separate transaction (it's most performant if we // bunch it into small transactions, but if we are doing a sync on login, it has to be the same // transaction) boolean requiresNew = splitTxns || AlfrescoTransactionSupport.getTransactionReadState() == TxnReadState.TXN_READ_ONLY; try { /** * Do the sync with the specified plugin */ syncWithPlugin(id, plugin, forceUpdate, isFullSync, requiresNew, visitedZoneIds, allZoneIds); this.applicationEventPublisher.publishEvent(new SynchronizeDirectoryEndEvent(this, id)); } catch (final RuntimeException e) { notifySyncDirectoryEnd(id, e); throw e; } } // if plugin exists } // for each instanceId //End of successful synchronization here notifySyncEnd(); } catch (final RuntimeException e) { notifySyncEnd(e); ChainingUserRegistrySynchronizer.logger.error("Synchronization aborted due to error", e); throw e; } finally { // Release the lock if necessary if (lockToken != null) { // Cancel the lock refresher // Because we may hit a perfect storm when trying to interrupt workers in their unsynchronized getTask() // method we can't wait indefinitely and may have to retry the shutdown int trys = 0; do { lockRefresher.shutdown(); try { lockRefresher.awaitTermination(ChainingUserRegistrySynchronizer.LOCK_TTL, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { } } while (!lockRefresher.isTerminated() && trys++ < 3); if (!lockRefresher.isTerminated()) { lockRefresher.shutdownNow(); ChainingUserRegistrySynchronizer.logger.error("Failed to shut down lock refresher"); } final String token = lockToken; this.transactionService.getRetryingTransactionHelper() .doInTransaction(new RetryingTransactionCallback<Object>() { public Object execute() throws Throwable { ChainingUserRegistrySynchronizer.this.jobLockService.releaseLock(token, ChainingUserRegistrySynchronizer.LOCK_QNAME); return null; } }, false, splitTxns); } } }
From source file:org.alfresco.repo.security.sync.TenantChainingUserRegistrySynchronizer.java
private void synchronizeInternal(boolean forceUpdate, boolean isFullSync, final boolean splitTxns) { TenantChainingUserRegistrySynchronizer.logger .debug("Running a sync for domain: " + SEIPTenantIntegration.getTenantId()); if (TenantChainingUserRegistrySynchronizer.logger.isDebugEnabled()) { if (forceUpdate) { TenantChainingUserRegistrySynchronizer.logger.debug("Running a full sync."); } else {/*from w ww.j a v a 2s . co m*/ TenantChainingUserRegistrySynchronizer.logger.debug("Running a differential sync."); } if (allowDeletions) { TenantChainingUserRegistrySynchronizer.logger.debug("deletions are allowed"); } else { TenantChainingUserRegistrySynchronizer.logger.debug("deletions are not allowed"); } // Don't proceed with the sync if the repository is read only if (this.transactionService.isReadOnly()) { TenantChainingUserRegistrySynchronizer.logger .warn("Unable to proceed with user registry synchronization. Repository is read only."); return; } } // Don't proceed with the sync if the repository is read only if (this.transactionService.isReadOnly()) { TenantChainingUserRegistrySynchronizer.logger .warn("Unable to proceed with user registry synchronization. Repository is read only."); return; } // Create a background executor that will refresh our lock. This means // we can request a lock with a relatively // small persistence time and not worry about it lasting after server // restarts. Note we use an independent // executor because this is a compound operation that spans accross // multiple batch processors. String lockToken = null; TraceableThreadFactory threadFactory = new TraceableThreadFactory(); threadFactory.setNamePrefix("TenantChainingUserRegistrySynchronizer lock refresh"); threadFactory.setThreadDaemon(true); ScheduledExecutorService lockRefresher = new ScheduledThreadPoolExecutor(1, threadFactory); // Let's ensure all exceptions get logged try { // First, try to obtain a lock to ensure we are the only node trying // to run this job try { if (splitTxns) { // If this is an automated sync on startup or scheduled // sync, don't even wait around for the lock. // Assume the sync will be completed on another node. lockToken = this.transactionService.getRetryingTransactionHelper() .doInTransaction(new RetryingTransactionCallback<String>() { public String execute() throws Throwable { return TenantChainingUserRegistrySynchronizer.this.jobLockService.getLock( TenantChainingUserRegistrySynchronizer.LOCK_QNAME, TenantChainingUserRegistrySynchronizer.LOCK_TTL, 0, 1); } }, false, splitTxns); } else { // If this is a login-triggered sync, give it a few retries // before giving up lockToken = this.jobLockService.getLock(TenantChainingUserRegistrySynchronizer.LOCK_QNAME, TenantChainingUserRegistrySynchronizer.LOCK_TTL, 3000, 10); } } catch (LockAcquisitionException e) { // Don't proceed with the sync if it is running on another node TenantChainingUserRegistrySynchronizer.logger.warn( "User registry synchronization already running in another thread. Synchronize aborted"); return; } // Schedule the lock refresh to run at regular intervals final String token = lockToken; lockRefresher.scheduleAtFixedRate(new Runnable() { public void run() { TenantChainingUserRegistrySynchronizer.this.transactionService.getRetryingTransactionHelper() .doInTransaction(new RetryingTransactionCallback<Object>() { public Object execute() throws Throwable { TenantChainingUserRegistrySynchronizer.this.jobLockService.refreshLock(token, TenantChainingUserRegistrySynchronizer.LOCK_QNAME, TenantChainingUserRegistrySynchronizer.LOCK_TTL); return null; } }, false, splitTxns); } }, TenantChainingUserRegistrySynchronizer.LOCK_TTL / 2, TenantChainingUserRegistrySynchronizer.LOCK_TTL / 2, TimeUnit.MILLISECONDS); Set<String> visitedZoneIds = new TreeSet<String>(); Collection<String> instanceIds = this.applicationContextManager.getInstanceIds(); // Work out the set of all zone IDs in the authentication chain so // that we can decide which users / groups // need 're-zoning' Set<String> allZoneIds = new TreeSet<String>(); for (String id : instanceIds) { allZoneIds.add(AuthorityService.ZONE_AUTH_EXT_PREFIX + id); } for (String id : instanceIds) { ApplicationContext context = this.applicationContextManager.getApplicationContext(id); try { UserRegistry plugin = (UserRegistry) context.getBean(this.sourceBeanName); if (!(plugin instanceof ActivateableBean) || ((ActivateableBean) plugin).isActive()) { if (TenantChainingUserRegistrySynchronizer.logger.isDebugEnabled()) { mbeanServer = (MBeanServerConnection) getApplicationContext() .getBean("alfrescoMBeanServer"); try { StringBuilder nameBuff = new StringBuilder(200).append( "Alfresco:Type=Configuration,Category=Authentication,id1=managed,id2=") .append(URLDecoder.decode(id, "UTF-8")); ObjectName name = new ObjectName(nameBuff.toString()); if (mbeanServer != null && mbeanServer.isRegistered(name)) { MBeanInfo info = mbeanServer.getMBeanInfo(name); MBeanAttributeInfo[] attributes = info.getAttributes(); TenantChainingUserRegistrySynchronizer.logger.debug(id + " attributes:"); for (MBeanAttributeInfo attribute : attributes) { Object value = mbeanServer.getAttribute(name, attribute.getName()); TenantChainingUserRegistrySynchronizer.logger .debug(attribute.getName() + " = " + value); } } } catch (UnsupportedEncodingException e) { if (TenantChainingUserRegistrySynchronizer.logger.isWarnEnabled()) { TenantChainingUserRegistrySynchronizer.logger.warn("Exception during logging", e); } } catch (MalformedObjectNameException e) { if (TenantChainingUserRegistrySynchronizer.logger.isWarnEnabled()) { TenantChainingUserRegistrySynchronizer.logger.warn("Exception during logging", e); } } catch (InstanceNotFoundException e) { if (TenantChainingUserRegistrySynchronizer.logger.isWarnEnabled()) { TenantChainingUserRegistrySynchronizer.logger.warn("Exception during logging", e); } } catch (IntrospectionException e) { if (TenantChainingUserRegistrySynchronizer.logger.isWarnEnabled()) { TenantChainingUserRegistrySynchronizer.logger.warn("Exception during logging", e); } } catch (AttributeNotFoundException e) { if (TenantChainingUserRegistrySynchronizer.logger.isWarnEnabled()) { TenantChainingUserRegistrySynchronizer.logger.warn("Exception during logging", e); } } catch (ReflectionException e) { if (TenantChainingUserRegistrySynchronizer.logger.isWarnEnabled()) { TenantChainingUserRegistrySynchronizer.logger.warn("Exception during logging", e); } } catch (MBeanException e) { if (TenantChainingUserRegistrySynchronizer.logger.isWarnEnabled()) { TenantChainingUserRegistrySynchronizer.logger.warn("Exception during logging", e); } } catch (IOException e) { if (TenantChainingUserRegistrySynchronizer.logger.isWarnEnabled()) { TenantChainingUserRegistrySynchronizer.logger.warn("Exception during logging", e); } } } if (TenantChainingUserRegistrySynchronizer.logger.isInfoEnabled()) { TenantChainingUserRegistrySynchronizer.logger .info("Synchronizing users and groups with user registry '" + id + "'"); } if (isFullSync && TenantChainingUserRegistrySynchronizer.logger.isWarnEnabled()) { TenantChainingUserRegistrySynchronizer.logger .warn("Full synchronization with user registry '" + id + "'"); if (allowDeletions) { TenantChainingUserRegistrySynchronizer.logger.warn( "Some users and groups previously created by synchronization with this user registry may be removed."); } else { TenantChainingUserRegistrySynchronizer.logger.warn( "Deletions are disabled. Users and groups removed from this registry will be logged only and will remain in the repository. Users previously found in a different registry will be moved in the repository rather than recreated."); } } // Work out whether we should do the work in a separate // transaction (it's most performant if we // bunch it into small transactions, but if we are doing // a sync on login, it has to be the same // transaction) boolean requiresNew = splitTxns || AlfrescoTransactionSupport .getTransactionReadState() == TxnReadState.TXN_READ_ONLY; syncWithPlugin(id, plugin, forceUpdate, isFullSync, requiresNew, visitedZoneIds, allZoneIds); } } catch (NoSuchBeanDefinitionException e) { // Ignore and continue } } } catch (RuntimeException e) { TenantChainingUserRegistrySynchronizer.logger.error("Synchronization aborted due to error", e); throw e; } // Release the lock if necessary finally { if (lockToken != null) { // Cancel the lock refresher // Because we may hit a perfect storm when trying to interrupt // workers in their unsynchronized getTask() // method we can't wait indefinitely and may have to retry the // shutdown int trys = 0; do { lockRefresher.shutdown(); try { lockRefresher.awaitTermination(TenantChainingUserRegistrySynchronizer.LOCK_TTL, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { } } while (!lockRefresher.isTerminated() && trys++ < 3); if (!lockRefresher.isTerminated()) { lockRefresher.shutdownNow(); TenantChainingUserRegistrySynchronizer.logger.error("Failed to shut down lock refresher"); } final String token = lockToken; this.transactionService.getRetryingTransactionHelper() .doInTransaction(new RetryingTransactionCallback<Object>() { public Object execute() throws Throwable { TenantChainingUserRegistrySynchronizer.this.jobLockService.releaseLock(token, TenantChainingUserRegistrySynchronizer.LOCK_QNAME); return null; } }, false, splitTxns); } } }
From source file:org.cggh.repo.security.sync.CustomChainingUserRegistrySynchronizer.java
private void synchronizeInternal(boolean forceUpdate, boolean isFullSync, final boolean splitTxns) { if (CustomChainingUserRegistrySynchronizer.logger.isDebugEnabled()) { if (forceUpdate) { CustomChainingUserRegistrySynchronizer.logger.debug("Running a full sync."); } else {/*from w w w.ja v a2 s . c o m*/ CustomChainingUserRegistrySynchronizer.logger.debug("Running a differential sync."); } if (allowDeletions) { CustomChainingUserRegistrySynchronizer.logger.debug("deletions are allowed"); } else { CustomChainingUserRegistrySynchronizer.logger.debug("deletions are not allowed"); } // Don't proceed with the sync if the repository is read only if (this.transactionService.isReadOnly()) { CustomChainingUserRegistrySynchronizer.logger .warn("Unable to proceed with user registry synchronization. Repository is read only."); return; } } // Don't proceed with the sync if the repository is read only if (this.transactionService.isReadOnly()) { CustomChainingUserRegistrySynchronizer.logger .warn("Unable to proceed with user registry synchronization. Repository is read only."); return; } // Create a background executor that will refresh our lock. This means we can request a lock with a relatively // small persistence time and not worry about it lasting after server restarts. Note we use an independent // executor because this is a compound operation that spans accross multiple batch processors. String lockToken = null; TraceableThreadFactory threadFactory = new TraceableThreadFactory(); threadFactory.setNamePrefix("ChainingUserRegistrySynchronizer lock refresh"); threadFactory.setThreadDaemon(true); ScheduledExecutorService lockRefresher = new ScheduledThreadPoolExecutor(1, threadFactory); // Let's ensure all exceptions get logged try { // First, try to obtain a lock to ensure we are the only node trying to run this job try { if (splitTxns) { // If this is an automated sync on startup or scheduled sync, don't even wait around for the lock. // Assume the sync will be completed on another node. lockToken = this.transactionService.getRetryingTransactionHelper() .doInTransaction(new RetryingTransactionCallback<String>() { public String execute() throws Throwable { return CustomChainingUserRegistrySynchronizer.this.jobLockService.getLock( CustomChainingUserRegistrySynchronizer.LOCK_QNAME, CustomChainingUserRegistrySynchronizer.LOCK_TTL, 0, 1); } }, false, splitTxns); } else { // If this is a login-triggered sync, give it a few retries before giving up lockToken = this.jobLockService.getLock(CustomChainingUserRegistrySynchronizer.LOCK_QNAME, CustomChainingUserRegistrySynchronizer.LOCK_TTL, 3000, 10); } } catch (LockAcquisitionException e) { // Don't proceed with the sync if it is running on another node CustomChainingUserRegistrySynchronizer.logger.warn( "User registry synchronization already running in another thread. Synchronize aborted"); return; } // Schedule the lock refresh to run at regular intervals final String token = lockToken; lockRefresher.scheduleAtFixedRate(new Runnable() { public void run() { CustomChainingUserRegistrySynchronizer.this.transactionService.getRetryingTransactionHelper() .doInTransaction(new RetryingTransactionCallback<Object>() { public Object execute() throws Throwable { CustomChainingUserRegistrySynchronizer.this.jobLockService.refreshLock(token, CustomChainingUserRegistrySynchronizer.LOCK_QNAME, CustomChainingUserRegistrySynchronizer.LOCK_TTL); return null; } }, false, splitTxns); } }, CustomChainingUserRegistrySynchronizer.LOCK_TTL / 2, CustomChainingUserRegistrySynchronizer.LOCK_TTL / 2, TimeUnit.MILLISECONDS); Set<String> visitedZoneIds = new TreeSet<String>(); Collection<String> instanceIds = this.applicationContextManager.getInstanceIds(); // Work out the set of all zone IDs in the authentication chain so that we can decide which users / groups // need 're-zoning' Set<String> allZoneIds = new TreeSet<String>(); for (String id : instanceIds) { allZoneIds.add(AuthorityService.ZONE_AUTH_EXT_PREFIX + id); } // Collect the plugins that we can sync : zoneId, plugin Map<String, UserRegistry> plugins = new HashMap<String, UserRegistry>(); for (String id : instanceIds) { UserRegistry plugin; try { ApplicationContext context = this.applicationContextManager.getApplicationContext(id); plugin = (UserRegistry) context.getBean(this.sourceBeanName); } catch (RuntimeException e) { // The bean doesn't exist or this subsystem won't start. The reason would have been logged. Ignore and continue. continue; } if (!(plugin instanceof ActivateableBean) || ((ActivateableBean) plugin).isActive()) { // yes this plugin needs to be synced plugins.put(id, plugin); } } /** * Sync starts here */ notifySyncStart(plugins.keySet()); for (String id : instanceIds) { UserRegistry plugin = plugins.get(id); if (plugin != null) { // If debug is enabled then dump out the contents of the authentication JMX bean if (CustomChainingUserRegistrySynchronizer.logger.isDebugEnabled()) { mbeanServer = (MBeanServerConnection) getApplicationContext() .getBean("alfrescoMBeanServer"); try { StringBuilder nameBuff = new StringBuilder(200) .append("Alfresco:Type=Configuration,Category=Authentication,id1=managed,id2=") .append(URLDecoder.decode(id, "UTF-8")); ObjectName name = new ObjectName(nameBuff.toString()); if (mbeanServer != null && mbeanServer.isRegistered(name)) { MBeanInfo info = mbeanServer.getMBeanInfo(name); MBeanAttributeInfo[] attributes = info.getAttributes(); CustomChainingUserRegistrySynchronizer.logger.debug(id + " attributes:"); for (MBeanAttributeInfo attribute : attributes) { Object value = mbeanServer.getAttribute(name, attribute.getName()); CustomChainingUserRegistrySynchronizer.logger .debug(attribute.getName() + " = " + value); } } } catch (UnsupportedEncodingException e) { if (CustomChainingUserRegistrySynchronizer.logger.isWarnEnabled()) { CustomChainingUserRegistrySynchronizer.logger.warn("Exception during logging", e); } } catch (MalformedObjectNameException e) { if (CustomChainingUserRegistrySynchronizer.logger.isWarnEnabled()) { CustomChainingUserRegistrySynchronizer.logger.warn("Exception during logging", e); } } catch (InstanceNotFoundException e) { if (CustomChainingUserRegistrySynchronizer.logger.isWarnEnabled()) { CustomChainingUserRegistrySynchronizer.logger.warn("Exception during logging", e); } } catch (IntrospectionException e) { if (CustomChainingUserRegistrySynchronizer.logger.isWarnEnabled()) { CustomChainingUserRegistrySynchronizer.logger.warn("Exception during logging", e); } } catch (AttributeNotFoundException e) { if (CustomChainingUserRegistrySynchronizer.logger.isWarnEnabled()) { CustomChainingUserRegistrySynchronizer.logger.warn("Exception during logging", e); } } catch (ReflectionException e) { if (CustomChainingUserRegistrySynchronizer.logger.isWarnEnabled()) { CustomChainingUserRegistrySynchronizer.logger.warn("Exception during logging", e); } } catch (MBeanException e) { if (CustomChainingUserRegistrySynchronizer.logger.isWarnEnabled()) { CustomChainingUserRegistrySynchronizer.logger.warn("Exception during logging", e); } } catch (IOException e) { if (CustomChainingUserRegistrySynchronizer.logger.isWarnEnabled()) { CustomChainingUserRegistrySynchronizer.logger.warn("Exception during logging", e); } } } // end of debug dump of active JMX bean if (CustomChainingUserRegistrySynchronizer.logger.isInfoEnabled()) { CustomChainingUserRegistrySynchronizer.logger .info("Synchronizing users and groups with user registry '" + id + "'"); } if (isFullSync && CustomChainingUserRegistrySynchronizer.logger.isWarnEnabled()) { CustomChainingUserRegistrySynchronizer.logger .warn("Full synchronization with user registry '" + id + "'"); if (allowDeletions) { CustomChainingUserRegistrySynchronizer.logger.warn( "Some users and groups previously created by synchronization with this user registry may be removed."); } else { CustomChainingUserRegistrySynchronizer.logger.warn( "Deletions are disabled. Users and groups removed from this registry will be logged only and will remain in the repository. Users previously found in a different registry will be moved in the repository rather than recreated."); } } // Work out whether we should do the work in a separate transaction (it's most performant if we // bunch it into small transactions, but if we are doing a sync on login, it has to be the same // transaction) boolean requiresNew = splitTxns || AlfrescoTransactionSupport.getTransactionReadState() == TxnReadState.TXN_READ_ONLY; try { /** * Do the sync with the specified plugin */ syncWithPlugin(id, plugin, forceUpdate, isFullSync, requiresNew, visitedZoneIds, allZoneIds); this.applicationEventPublisher.publishEvent(new SynchronizeDirectoryEndEvent(this, id)); } catch (final RuntimeException e) { notifySyncDirectoryEnd(id, e); throw e; } } // if plugin exists } // for each instanceId //End of successful synchronization here notifySyncEnd(); } catch (final RuntimeException e) { notifySyncEnd(e); CustomChainingUserRegistrySynchronizer.logger.error("Synchronization aborted due to error", e); throw e; } finally { // Release the lock if necessary if (lockToken != null) { // Cancel the lock refresher // Because we may hit a perfect storm when trying to interrupt workers in their unsynchronized getTask() // method we can't wait indefinitely and may have to retry the shutdown int trys = 0; do { lockRefresher.shutdown(); try { lockRefresher.awaitTermination(CustomChainingUserRegistrySynchronizer.LOCK_TTL, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { } } while (!lockRefresher.isTerminated() && trys++ < 3); if (!lockRefresher.isTerminated()) { lockRefresher.shutdownNow(); CustomChainingUserRegistrySynchronizer.logger.error("Failed to shut down lock refresher"); } final String token = lockToken; this.transactionService.getRetryingTransactionHelper() .doInTransaction(new RetryingTransactionCallback<Object>() { public Object execute() throws Throwable { CustomChainingUserRegistrySynchronizer.this.jobLockService.releaseLock(token, CustomChainingUserRegistrySynchronizer.LOCK_QNAME); return null; } }, false, splitTxns); } } }