/** @see DiscoveryServerService#mergeInventoryReport(InventoryReport) */
  @Override
  public MergeInventoryReportResults mergeInventoryReport(InventoryReport report)
      throws InvalidInventoryReportException, StaleTypeException {

    InventoryReportSerializer.getSingleton().lock(report.getAgent().getName());
    try {
      long start = System.currentTimeMillis();
      DiscoveryBossLocal discoveryBoss = LookupUtil.getDiscoveryBoss();
      MergeInventoryReportResults results;
      try {
        results = discoveryBoss.mergeInventoryReport(report);
      } catch (StaleTypeException e) {
        // There is no need to log this exception as it is part of a normal work flow
        // that occurs as a result of a user deleting a plugin. DiscoveryBossBean
        // already logs a message about the stale types that can be useful for
        // debugging; so, we just need to propagate the exception to the agent.
        throw e;
      } catch (InvalidInventoryReportException e) {
        Agent agent = report.getAgent();
        if (log.isDebugEnabled()) {
          log.error("Received invalid inventory report from agent [" + agent + "]", e);
        } else {
          /*
           * this is expected when the platform is uninventoried, because the agent often has in-flight reports
           * going to the server at the time the platform's agent is being deleted from the database
           */
          log.error(
              "Received invalid inventory report from agent [" + agent + "]: " + e.getMessage());
        }
        throw e;
      } catch (RuntimeException e) {
        log.error(
            "Fatal error occurred during merging of inventory report from agent ["
                + report.getAgent()
                + "].",
            e);
        throw e;
      }

      long elapsed = (System.currentTimeMillis() - start);
      if (elapsed > 30000L) {
        log.warn("Performance: inventory merge (" + elapsed + ")ms");
      } else {
        if (log.isDebugEnabled()) {
          log.debug("Performance: inventory merge (" + elapsed + ")ms");
        }
      }

      return results;
    } finally {
      InventoryReportSerializer.getSingleton().unlock(report.getAgent().getName());
    }
  }
  @Test(dependsOnMethods = "testPluginLoad")
  public void testServerDiscovery() throws Exception {
    InventoryReport report =
        PluginContainer.getInstance().getInventoryManager().executeServerScanImmediately();
    assert report != null;
    System.out.println("Discovery took: " + (report.getEndTime() - report.getStartTime()) + "ms");

    Resource platform = PluginContainer.getInstance().getInventoryManager().getPlatform();
    Set<Resource> servers = platform.getChildResources();

    // assert servers.size() != 0; Don't require a running app server for testing at this point
    System.out.println("Found " + servers.size() + " servers");
  }