@Test
  public void testRequiredServerConnectorInfo() throws Exception {
    AsyncConnectorInfoManager manager =
        localConnectorFramework.get().getRemoteManager(CONNECTION_INFO);
    Assert.assertNotNull(manager);

    manager = serverConnectorFramework.get().getServerManager("anonymous");
    Assert.assertNotNull(manager);

    ConnectorInfo c =
        manager
            .findConnectorInfoAsync(getTestConnectorKey())
            .getOrThrowUninterruptibly(5, TimeUnit.MINUTES);
    Assert.assertNotNull(c);

    Assert.assertNotNull(
        manager
            .findConnectorInfoAsync(getTestStatefulConnectorKey())
            .getOrThrowUninterruptibly(30, TimeUnit.SECONDS));

    Assert.assertNotNull(
        manager
            .findConnectorInfoAsync(getTestPoolableStatefulConnectorKey())
            .getOrThrowUninterruptibly(30, TimeUnit.SECONDS));

    for (ConnectorInfo ci : manager.getConnectorInfos()) {
      Reporter.log(String.valueOf(ci.getConnectorKey()), true);
    }
  }
 @Override
 public ConnectorInfo findConnectorInfo(ConnectorKey key) {
   for (Pair<Bundle, List<ConnectorInfo>> bundle : connectorInfoCache.values()) {
     for (ConnectorInfo info : bundle.second) {
       if (info.getConnectorKey().equals(key)) {
         return info;
       }
     }
   }
   return null;
 }
 @Override
 public void removingEntries(Bundle bundle, List<ManifestEntry> list) {
   NullArgumentException.validateNotNull(bundle, "Bundle");
   synchronized (connectorInfoCache) {
     Pair<Bundle, List<ConnectorInfo>> info = connectorInfoCache.remove(bundle.getSymbolicName());
     if (null != info) {
       for (ConnectorInfo connectorInfo : info.second) {
         notifyListeners(
             buildEvent(
                 ConnectorEvent.CONNECTOR_UNREGISTERING,
                 info.first,
                 connectorInfo.getConnectorKey()));
       }
     }
   }
   logger.info("Remove Connector {}, list: {}", bundle.getSymbolicName(), list);
 }
 /** {@inheritDoc} */
 @Override
 public void addConnectorEventHandler(ConnectorEventHandler hook) {
   if (hook == null) {
     throw new NullPointerException();
   }
   if (!eventHandlers.contains(hook)) {
     // TODO: hook is not wired to the listeners and it's not called if a
     // new connector registered meanwhile
     for (Map.Entry<String, Pair<Bundle, List<ConnectorInfo>>> entry :
         connectorInfoCache.entrySet()) {
       for (ConnectorInfo connectorInfo : entry.getValue().second) {
         hook.handleEvent(
             buildEvent(
                 ConnectorEvent.CONNECTOR_REGISTERED,
                 entry.getValue().first,
                 connectorInfo.getConnectorKey()));
       }
     }
     eventHandlers.addElement(hook);
   }
 }
 @Override
 public void addingEntries(Bundle bundle, List<ManifestEntry> list) {
   NullArgumentException.validateNotNull(bundle, "Bundle");
   NullArgumentException.validateNotNull(list, "ManifestEntry");
   synchronized (connectorInfoCache) {
     if (!connectorInfoCache.containsKey(bundle.getSymbolicName())) {
       Pair<Bundle, List<ConnectorInfo>> info = processBundle(bundle, list);
       if (null != info) {
         connectorInfoCache.put(bundle.getSymbolicName(), info);
         for (ConnectorInfo connectorInfo : info.second) {
           notifyListeners(
               buildEvent(
                   ConnectorEvent.CONNECTOR_REGISTERED,
                   info.first,
                   connectorInfo.getConnectorKey()));
         }
       }
       logger.info("Add Connector {}, list: {}", bundle.getSymbolicName(), list);
     }
   }
 }
 @Override
 public ConnectorFacade newInstance(ConnectorInfo connectorInfo, String config) {
   ConnectorFacade ret = null;
   if (connectorInfo instanceof LocalConnectorInfoImpl) {
     LocalConnectorInfoImpl localInfo = (LocalConnectorInfoImpl) connectorInfo;
     try {
       // create a new Provisioner..
       ret = new LocalConnectorFacadeImpl(localInfo, config);
     } catch (Exception ex) {
       String connector = connectorInfo.getConnectorKey().toString();
       logger.error(
           "Failed to create new connector facade: {}, {}", new Object[] {connector, config}, ex);
       throw ConnectorException.wrap(ex);
     }
   } else {
     throw new ConnectorException("RemoteConnector not supported!");
   }
   return ret;
 }
  /**
   * Transforms midPoint XML configuration of the connector to the ICF configuration.
   *
   * <p>The "configuration" part of the XML resource definition will be used.
   *
   * <p>The provided ICF APIConfiguration will be modified, some values may be overwritten.
   *
   * @param apiConfig ICF connector configuration
   * @param resourceType midPoint XML configuration
   * @throws SchemaException
   * @throws ConfigurationException
   */
  public APIConfiguration transformConnectorConfiguration(PrismContainerValue configuration)
      throws SchemaException, ConfigurationException {

    APIConfiguration apiConfig = cinfo.createDefaultAPIConfiguration();
    ConfigurationProperties configProps = apiConfig.getConfigurationProperties();

    // The namespace of all the configuration properties specific to the
    // connector instance will have a connector instance namespace. This
    // namespace can be found in the resource definition.
    String connectorConfNs = connectorType.getNamespace();

    PrismContainer configurationPropertiesContainer =
        configuration.findContainer(
            ConnectorFactoryIcfImpl.CONNECTOR_SCHEMA_CONFIGURATION_PROPERTIES_ELEMENT_QNAME);
    if (configurationPropertiesContainer == null) {
      // Also try this. This is an older way.
      configurationPropertiesContainer =
          configuration.findContainer(
              new QName(
                  connectorConfNs,
                  ConnectorFactoryIcfImpl
                      .CONNECTOR_SCHEMA_CONFIGURATION_PROPERTIES_ELEMENT_LOCAL_NAME));
    }

    transformConnectorConfiguration(configProps, configurationPropertiesContainer, connectorConfNs);

    PrismContainer connectorPoolContainer =
        configuration.findContainer(
            new QName(
                ConnectorFactoryIcfImpl.NS_ICF_CONFIGURATION,
                ConnectorFactoryIcfImpl
                    .CONNECTOR_SCHEMA_CONNECTOR_POOL_CONFIGURATION_XML_ELEMENT_NAME));
    ObjectPoolConfiguration connectorPoolConfiguration = apiConfig.getConnectorPoolConfiguration();
    transformConnectorPoolConfiguration(connectorPoolConfiguration, connectorPoolContainer);

    PrismProperty producerBufferSizeProperty =
        configuration.findProperty(
            new QName(
                ConnectorFactoryIcfImpl.NS_ICF_CONFIGURATION,
                ConnectorFactoryIcfImpl.CONNECTOR_SCHEMA_PRODUCER_BUFFER_SIZE_XML_ELEMENT_NAME));
    if (producerBufferSizeProperty != null) {
      apiConfig.setProducerBufferSize(parseInt(producerBufferSizeProperty));
    }

    PrismContainer connectorTimeoutsContainer =
        configuration.findContainer(
            new QName(
                ConnectorFactoryIcfImpl.NS_ICF_CONFIGURATION,
                ConnectorFactoryIcfImpl.CONNECTOR_SCHEMA_TIMEOUTS_XML_ELEMENT_NAME));
    transformConnectorTimeoutsConfiguration(apiConfig, connectorTimeoutsContainer);

    PrismContainer resultsHandlerConfigurationContainer =
        configuration.findContainer(
            new QName(
                ConnectorFactoryIcfImpl.NS_ICF_CONFIGURATION,
                ConnectorFactoryIcfImpl
                    .CONNECTOR_SCHEMA_RESULTS_HANDLER_CONFIGURATION_ELEMENT_LOCAL_NAME));
    ResultsHandlerConfiguration resultsHandlerConfiguration =
        apiConfig.getResultsHandlerConfiguration();
    transformResultsHandlerConfiguration(
        resultsHandlerConfiguration, resultsHandlerConfigurationContainer);

    return apiConfig;
  }