// performance issue related fix : IT 15784
 private void registerTransparentDynamicReconfigPool(
     PoolInfo poolInfo, JdbcConnectionPool resourcePool) {
   ConnectorRegistry registry = ConnectorRegistry.getInstance();
   if (ConnectorsUtil.isDynamicReconfigurationEnabled(resourcePool)) {
     registry.addTransparentDynamicReconfigPool(poolInfo);
   } else {
     registry.removeTransparentDynamicReconfigPool(poolInfo);
   }
 }
 /**
  * Undeploy the resource from the server's runtime naming context
  *
  * @param poolInfo a resource object
  * @throws UnsupportedOperationException Currently we are not supporting this method.
  */
 private synchronized void actualUndeployResource(PoolInfo poolInfo) throws Exception {
   runtime.deleteConnectorConnectionPool(poolInfo);
   // performance issue related fix : IT 15784
   ConnectorRegistry.getInstance().removeTransparentDynamicReconfigPool(poolInfo);
   if (_logger.isLoggable(Level.FINEST)) {
     _logger.finest("Pool Undeployed");
   }
 }
  private void handlePoolRecreationForExistingProxies(ConnectorConnectionPool connConnPool) {

    recreatePool(connConnPool);

    Collection<BindableResource> resourcesList;
    if (!connConnPool.isApplicationScopedResource()) {
      resourcesList =
          JdbcResourcesUtil.getResourcesOfPool(domain.getResources(), connConnPool.getName());
    } else {
      PoolInfo poolInfo = connConnPool.getPoolInfo();
      Resources resources = ResourcesUtil.createInstance().getResources(poolInfo);
      resourcesList = JdbcResourcesUtil.getResourcesOfPool(resources, connConnPool.getName());
    }
    for (BindableResource bindableResource : resourcesList) {

      ResourceInfo resourceInfo = ConnectorsUtil.getResourceInfo(bindableResource);
      ConnectorRegistry.getInstance().updateResourceInfoVersion(resourceInfo);
    }
  }
  private void handlePoolRecreation(final ConnectorConnectionPool connConnPool)
      throws ConnectorRuntimeException {
    debug("[DRC] Pool recreation required");

    final long reconfigWaitTimeout = connConnPool.getDynamicReconfigWaitTimeout();
    PoolInfo poolInfo =
        new PoolInfo(
            connConnPool.getName(),
            connConnPool.getApplicationName(),
            connConnPool.getModuleName());
    final ResourcePool oldPool = runtime.getPoolManager().getPool(poolInfo);

    if (reconfigWaitTimeout > 0) {

      oldPool.blockRequests(reconfigWaitTimeout);

      if (oldPool.getPoolWaitQueue().getQueueLength() > 0
          || oldPool.getPoolStatus().getNumConnUsed() > 0) {

        Runnable thread =
            new Runnable() {
              @Override
              public void run() {
                try {

                  long numSeconds = 5000L; // poll every 5 seconds
                  long steps = reconfigWaitTimeout / numSeconds;
                  if (steps == 0) {
                    waitForCompletion(steps, oldPool, reconfigWaitTimeout);
                  } else {
                    for (long i = 0; i < steps; i++) {
                      waitForCompletion(steps, oldPool, reconfigWaitTimeout);
                      if (oldPool.getPoolWaitQueue().getQueueLength() == 0
                          && oldPool.getPoolStatus().getNumConnUsed() == 0) {
                        debug("wait-queue is empty and num-con-used is 0");
                        break;
                      }
                    }
                  }

                  handlePoolRecreationForExistingProxies(connConnPool);

                  PoolWaitQueue reconfigWaitQueue = oldPool.getReconfigWaitQueue();
                  debug("checking reconfig-wait-queue for notification");
                  if (reconfigWaitQueue.getQueueContents().size() > 0) {
                    for (Object o : reconfigWaitQueue.getQueueContents()) {
                      debug("notifying reconfig-wait-queue object [ " + o + " ]");
                      synchronized (o) {
                        o.notify();
                      }
                    }
                  }
                } catch (InterruptedException ie) {
                  if (_logger.isLoggable(Level.FINEST)) {
                    _logger.log(
                        Level.FINEST,
                        "Interrupted while waiting for all existing clients to return connections to pool",
                        ie);
                  }
                }

                if (_logger.isLoggable(Level.FINEST)) {
                  _logger.finest(
                      "woke-up after giving time for in-use connections to return, "
                          + "WaitQueue-Length : ["
                          + oldPool.getPoolWaitQueue().getQueueContents()
                          + "], "
                          + "Num-Conn-Used : ["
                          + oldPool.getPoolStatus().getNumConnUsed()
                          + "]");
                }
              }
            };

        Callable c = Executors.callable(thread);
        ArrayList list = new ArrayList();
        list.add(c);
        try {
          execService.invokeAll(list);
        } catch (Exception e) {
          Object[] params = new Object[] {connConnPool.getName(), e};
          _logger.log(Level.WARNING, "exception.redeploying.pool.transparently", params);
        }

      } else {
        handlePoolRecreationForExistingProxies(connConnPool);
      }
    } else if (oldPool.getReconfigWaitTime() > 0) {
      // reconfig is being switched off, invalidate proxies
      Collection<BindableResource> resources =
          JdbcResourcesUtil.getResourcesOfPool(
              runtime.getResources(oldPool.getPoolInfo()), oldPool.getPoolInfo().getName());
      ConnectorRegistry registry = ConnectorRegistry.getInstance();
      for (BindableResource resource : resources) {
        ResourceInfo resourceInfo = ConnectorsUtil.getResourceInfo(resource);
        registry.removeResourceFactories(resourceInfo);
      }
      // recreate the pool now.
      recreatePool(connConnPool);
    } else {
      recreatePool(connConnPool);
    }
  }