/**
   * getServiceTypeNames
   *
   * @return a {@link java.util.Collection} object.
   */
  @Override
  public Collection<String> getServiceTypeNames(String groupName) {
    final SortedSet<String> serviceNames = new TreeSet<String>();

    m_readLock.lock();
    try {
      m_pendingForeignSourceRepository.flush();
      final ForeignSource pendingForeignSource =
          m_pendingForeignSourceRepository.getForeignSource(groupName);
      serviceNames.addAll(pendingForeignSource.getDetectorNames());

      m_deployedForeignSourceRepository.flush();
      final ForeignSource deployedForeignSource =
          m_deployedForeignSourceRepository.getForeignSource(groupName);
      serviceNames.addAll(deployedForeignSource.getDetectorNames());

      for (final OnmsServiceType type : m_serviceTypeDao.findAll()) {
        serviceNames.add(type.getName());
      }
      serviceNames.addAll(m_capsdConfig.getConfiguredProtocols());
      return serviceNames;
    } finally {
      m_readLock.unlock();
    }
  }
  /** {@inheritDoc} */
  public List<ServiceDetector> getDetectorsForForeignSource(final String foreignSourceName) {
    final ForeignSource foreignSource =
        m_foreignSourceRepository.getForeignSource(foreignSourceName);
    assertNotNull(foreignSource, "Expected a foreignSource with name %s", foreignSourceName);

    final List<PluginConfig> detectorConfigs = foreignSource.getDetectors();
    if (detectorConfigs == null) {
      return new ArrayList<ServiceDetector>(m_pluginRegistry.getAllPlugins(ServiceDetector.class));
    }

    final List<ServiceDetector> detectors = new ArrayList<ServiceDetector>(detectorConfigs.size());
    for (final PluginConfig detectorConfig : detectorConfigs) {
      final ServiceDetector detector =
          m_pluginRegistry.getPluginInstance(ServiceDetector.class, detectorConfig);
      if (detector == null) {
        errorf(this, "Configured plugin does not exist: %s", detectorConfig);
      } else {
        detector.setServiceName(detectorConfig.getName());
        detector.init();
        detectors.add(detector);
      }
    }

    return detectors;
  }
  private NodeScanSchedule createScheduleForNode(final OnmsNode node, final boolean force) {
    Assert.notNull(node, "Node may not be null");
    final String actualForeignSource = node.getForeignSource();
    if (actualForeignSource == null && !isDiscoveryEnabled()) {
      infof(
          this,
          "Not scheduling node %s to be scanned since it has a null foreignSource and handling of discovered nodes is disabled in provisiond",
          node);
      return null;
    }

    final String effectiveForeignSource =
        actualForeignSource == null ? "default" : actualForeignSource;
    try {
      final ForeignSource fs = m_foreignSourceRepository.getForeignSource(effectiveForeignSource);

      final Duration scanInterval = fs.getScanInterval();
      Duration initialDelay = Duration.ZERO;
      if (node.getLastCapsdPoll() != null && !force) {
        final DateTime nextPoll =
            new DateTime(node.getLastCapsdPoll().getTime()).plus(scanInterval);
        final DateTime now = new DateTime();
        if (nextPoll.isAfter(now)) {
          initialDelay = new Duration(now, nextPoll);
        }
      }

      return new NodeScanSchedule(
          node.getId(), actualForeignSource, node.getForeignId(), initialDelay, scanInterval);
    } catch (final ForeignSourceRepositoryException e) {
      warnf(this, e, "unable to get foreign source '%s' from repository", effectiveForeignSource);
      return null;
    }
  }
  /**
   * getPluginsForForeignSource
   *
   * @param pluginClass a {@link java.lang.Class} object.
   * @param foreignSourceName a {@link java.lang.String} object.
   * @param <T> a T object.
   * @return a {@link java.util.List} object.
   */
  public <T> List<T> getPluginsForForeignSource(
      final Class<T> pluginClass, final String foreignSourceName) {
    final ForeignSource foreignSource =
        m_foreignSourceRepository.getForeignSource(foreignSourceName);
    assertNotNull(foreignSource, "Expected a foreignSource with name %s", foreignSourceName);

    final List<PluginConfig> configs = foreignSource.getPolicies();
    if (configs == null) {
      return Collections.emptyList();
    }

    final List<T> plugins = new ArrayList<T>(configs.size());
    for (final PluginConfig config : configs) {
      final T plugin = m_pluginRegistry.getPluginInstance(pluginClass, config);
      if (plugin == null) {
        LogUtils.tracef(
            this,
            "Configured plugin is not appropropriate for policy class %s: %s",
            pluginClass,
            config);
      } else {
        plugins.add(plugin);
      }
    }

    return plugins;
  }
 private ForeignSource createForeignSource(String foreignSource) throws Exception {
   ForeignSource fs = new ForeignSource(foreignSource);
   fs.addDetector(
       new PluginConfig("HTTP", "org.opennms.netmgt.provision.detector.simple.HttpDetector"));
   fs.addPolicy(
       new PluginConfig(
           "all-ipinterfaces",
           "org.opennms.netmgt.provision.persist.policies.InclusiveInterfacePolicy"));
   m_foreignSourceRepository.save(fs);
   m_foreignSourceRepository.flush();
   return fs;
 }
  @Test
  public void integrationTest() {
    /*
     * First, the user creates a requisition in the UI, or RESTful
     * interface.
     */
    Requisition pendingReq = new Requisition("test");
    pendingReq.putNode(createNode("1"));
    m_pending.save(pendingReq);
    m_pending.flush();

    /*
     * Then, the user makes a foreign source configuration to go along
     * with that requisition.
     */
    ForeignSource pendingSource = m_repository.getForeignSource("test");
    assertTrue(pendingSource.isDefault());
    pendingSource.setDetectors(new ArrayList<PluginConfig>());
    m_pending.save(pendingSource);
    m_pending.flush();

    /*
     * Now we got an import event, so we import that requisition file,
     * and save it.  The ForeignSource in the pending repository should
     * match the one in the active one, now.
     */
    Requisition activeReq =
        m_repository.importResourceRequisition(
            new UrlResource(m_pending.getRequisitionURL("test")));
    ForeignSource activeSource = m_active.getForeignSource("test");
    // and the foreign source should be the same as the one we made earlier, only this time it's
    // active

    assertEquals(activeSource.getName(), pendingSource.getName());
    assertEquals(activeSource.getDetectorNames(), pendingSource.getDetectorNames());
    assertEquals(activeSource.getScanInterval(), pendingSource.getScanInterval());
    assertRequisitionsMatch("active and pending requisitions should match", activeReq, pendingReq);

    /*
     * Since it's been officially deployed, the requisition and foreign
     * source should no longer be in the pending repo.
     */
    assertNull(
        "the requisition should be null in the pending repo", m_pending.getRequisition("test"));
    assertTrue(
        "the foreign source should be default since there's no specific in the pending repo",
        m_pending.getForeignSource("test").isDefault());
  }
  @Test
  public void testForeignSource() throws Exception {
    createRequisition();
    ForeignSource foreignSource = createForeignSource(m_defaultForeignSourceName);
    Set<ForeignSource> foreignSources = m_foreignSourceRepository.getForeignSources();
    assertEquals("number of foreign sources must be 1", 1, foreignSources.size());
    assertEquals(
        "getAll() foreign source name must match",
        m_defaultForeignSourceName,
        foreignSources.iterator().next().getName());

    // check that the foreign source matches
    final ForeignSource newForeignSource =
        m_foreignSourceRepository.getForeignSource(m_defaultForeignSourceName);

    assertEquals(foreignSource.getName(), newForeignSource.getName());
    assertEquals(foreignSource.getDateStampAsDate(), newForeignSource.getDateStampAsDate());
    assertEquals(foreignSource.getDetectorNames(), newForeignSource.getDetectorNames());
    assertEquals(foreignSource.getScanInterval(), newForeignSource.getScanInterval());
  }
 @Test
 public void testDefaultForeignSource() throws Exception {
   createRequisition();
   List<String> detectorList =
       Arrays.asList(
           new String[] {
             "DNS", "FTP", "HTTP", "HTTPS", "ICMP", "IMAP", "LDAP", "NRPE", "POP3", "SMTP", "SNMP",
             "SSH"
           });
   String uuid = UUID.randomUUID().toString();
   ForeignSource defaultForeignSource = m_foreignSourceRepository.getForeignSource(uuid);
   assertEquals(
       "name must match requested foreign source repository name",
       uuid,
       defaultForeignSource.getName());
   assertEquals(
       "scan-interval must be 1 day",
       86400000,
       defaultForeignSource.getScanInterval().getMillis());
   assertEquals(
       "foreign source must have no default policies",
       0,
       defaultForeignSource.getPolicies().size());
   List<String> fsNames = new ArrayList<String>();
   for (PluginConfig config : defaultForeignSource.getDetectors()) {
     fsNames.add(config.getName());
   }
   assertEquals("detector list must match expected defaults", detectorList, fsNames);
   assertTrue("foreign source must be tagged as default", defaultForeignSource.isDefault());
 }
  private synchronized void cleanUpDeployedForeignSources(String foreignSourceName) {
    ForeignSource deployed = m_deployedForeignSourceRepository.getForeignSource(foreignSourceName);
    ForeignSource pending = m_pendingForeignSourceRepository.getForeignSource(foreignSourceName);

    if (pending.isDefault()) {
      // if pending is default, assume deployed is valid, be it default or otherwise
      m_pendingForeignSourceRepository.delete(pending);
    } else {
      if (deployed.isDefault()) {
        // if pending is not default, and deployed is, assume pending should override deployed
        m_deployedForeignSourceRepository.save(pending);
      } else {
        // otherwise, compare dates, pending updates deployed if it's timestamp is newer
        Date pendingDate = pending.getDateStampAsDate();
        Date deployedDate = deployed.getDateStampAsDate();
        if (!deployedDate.after(pendingDate)) {
          m_deployedForeignSourceRepository.save(pending);
        }
      }
    }
    m_pendingForeignSourceRepository.delete(pending);
  }