@Test
  public void publishIndex() throws Exception {
    File repositoryPath = new File(nexusWorkDir, "storage/nexus-test-harness-repo");
    File index = new File(repositoryPath, ".index");

    if (index.exists()) {
      // can't contain the OSS index
      MatcherAssert.assertThat(
          Arrays.asList(index.list()),
          CoreMatchers.not(
              IsCollectionContaining.hasItems(
                  "nexus-maven-repository-index.gz",
                  "nexus-maven-repository-index.gz.md5",
                  "nexus-maven-repository-index.gz.sha1",
                  "nexus-maven-repository-index.properties",
                  "nexus-maven-repository-index.properties.md5",
                  "nexus-maven-repository-index.properties.sha1",
                  "nexus-maven-repository-index.zip",
                  "nexus-maven-repository-index.zip.md5",
                  "nexus-maven-repository-index.zip.sha1")));
    }

    ScheduledServicePropertyResource prop = new ScheduledServicePropertyResource();
    prop.setKey("repositoryOrGroupId");
    prop.setValue("repo_nexus-test-harness-repo");

    TaskScheduleUtil.runTask(PublishIndexesTaskDescriptor.ID, prop);

    Assert.assertTrue(index.exists(), ".index should exists after publish index task was run.");
  }
  @Test
  public void testReindex() throws Exception {

    this.repositoryPath = new File(nexusWorkDir, "storage/" + this.getTestRepositoryId());
    logger.info("path: " + repositoryPath);
    File oldSnapshot = getTestFile("repo");

    // Copy artifact to avoid indexing
    FileUtils.copyDirectory(oldSnapshot, repositoryPath);

    // try to seach and fail
    List<NexusArtifact> search = getSearchMessageUtil().searchFor("nexus641");
    Assert.assertEquals(search.size(), 1, "The artifact was already indexed");

    // reindex
    ScheduledServicePropertyResource prop = new ScheduledServicePropertyResource();
    prop.setKey("repositoryId");
    prop.setValue(this.getTestRepositoryId());

    // reindex
    TaskScheduleUtil.runTask(UpdateIndexTaskDescriptor.ID, prop);

    // try to download again and success
    search = getSearchMessageUtil().searchFor("nexus641");
    Assert.assertEquals(search.size(), 2, "The artifact should be indexed");
  }
  protected void downloadApacheFelixWebManagement(final String repoId)
      throws IOException, Exception, MalformedURLException {
    FileUtils.deleteDirectory(new File(FELIX_HOME, "felix-cache"));

    final ScheduledServicePropertyResource prop = new ScheduledServicePropertyResource();
    prop.setKey("repositoryId");
    prop.setValue(repoId);

    TaskScheduleUtil.runTask("PublishObrDescriptorTask", prop);

    downloadFile(
        new URL(getRepositoryUrl(repoId) + ".meta/obr.xml"),
        "target/" + getTestId() + "/download/obr.xml");

    final ProcessBuilder pb =
        new ProcessBuilder(
            "java", "-Dfelix.config.properties=" + FELIX_CONF.toURI(), "-jar", "bin/felix.jar");

    pb.directory(FELIX_HOME);
    pb.redirectErrorStream(true);
    final Process p = pb.start();

    final Object lock = new Object();

    final Thread t =
        new Thread(
            new Runnable() {
              public void run() {
                // just a safeguard, if felix get stuck kill everything
                try {
                  synchronized (lock) {
                    lock.wait(5 * 1000 * 60);
                  }
                } catch (final InterruptedException e) {
                  // ignore
                }
                p.destroy();
              }
            });
    t.setDaemon(true);
    t.start();

    synchronized (lock) {
      final InputStream input = p.getInputStream();
      final OutputStream output = p.getOutputStream();
      waitFor(input, "g!");
      output.write(("obr:repos add " + getRepositoryUrl(repoId) + ".meta/obr.xml\r\n").getBytes());
      output.flush();
      waitFor(input, "g!");
      output.write("obr:deploy -s org.apache.felix.webconsole\r\n".getBytes());
      output.flush();
      waitFor(input, "done.");
      p.destroy();

      lock.notifyAll();
    }
  }
  @Test
  public void testIndexOptimizer() throws Exception {
    // reindex
    ScheduledServicePropertyResource prop = new ScheduledServicePropertyResource();
    prop.setKey("repositoryId");
    prop.setValue("nexus-test-harness-repo");

    // reindex
    TaskScheduleUtil.runTask(OptimizeIndexTaskDescriptor.ID, prop);
  }
  @Test
  public void rebuildAttributes() throws Exception {
    String attributePath = "proxy/attributes/nexus-test-harness-repo/nexus640/artifact/1.0.0/";

    ScheduledServicePropertyResource repo = new ScheduledServicePropertyResource();
    repo.setKey("repositoryOrGroupId");
    repo.setValue("repo_" + REPO_TEST_HARNESS_REPO);
    TaskScheduleUtil.runTask(RebuildAttributesTaskDescriptor.ID, repo);

    File jar = new File(nexusWorkDir, attributePath + "artifact-1.0.0.jar");
    Assert.assertTrue(jar.exists(), "Attribute files should be generated after rebuild");
    File pom = new File(nexusWorkDir, attributePath + "artifact-1.0.0.pom");
    Assert.assertTrue(pom.exists(), "Attribute files should be generated after rebuild");
  }
  protected List<ScheduledServicePropertyResource> formatServiceProperties(
      Map<String, String> map) {
    List<ScheduledServicePropertyResource> list = new ArrayList<ScheduledServicePropertyResource>();

    for (String key : map.keySet()) {
      if (!TaskUtils.isPrivateProperty(key)) {
        ScheduledServicePropertyResource prop = new ScheduledServicePropertyResource();
        prop.setKey(key);
        prop.setValue(map.get(key));
        list.add(prop);
      }
    }

    return list;
  }
  public NexusTask<?> getModelNexusTask(ScheduledServiceBaseResource model, Request request)
      throws IllegalArgumentException, ResourceException {
    String serviceType = model.getTypeId();

    NexusTask<?> task = (NexusTask<?>) getNexusScheduler().createTaskInstance(serviceType);

    for (Iterator iter = model.getProperties().iterator(); iter.hasNext(); ) {
      ScheduledServicePropertyResource prop = (ScheduledServicePropertyResource) iter.next();
      task.addParameter(prop.getKey(), prop.getValue());
    }

    TaskUtils.setAlertEmail(task, model.getAlertEmail());
    TaskUtils.setId(task, model.getId());
    TaskUtils.setName(task, model.getName());

    return task;
  }
  @Override
  public ScheduledServiceAdvancedResource getTaskScheduled() {
    if (scheduledTask == null) {
      scheduledTask = new ScheduledServiceAdvancedResource();
      scheduledTask.setEnabled(true);
      scheduledTask.setId(null);
      scheduledTask.setName("taskAdvanced");
      scheduledTask.setSchedule("advanced");
      // A future date
      Date startDate = DateUtils.addDays(new Date(), 10);
      startDate = DateUtils.round(startDate, Calendar.DAY_OF_MONTH);
      scheduledTask.setCronCommand("0 0 12 ? * WED");

      scheduledTask.setTypeId(UpdateIndexTaskDescriptor.ID);

      ScheduledServicePropertyResource prop = new ScheduledServicePropertyResource();
      prop.setKey("repositoryId");
      prop.setValue("all_repo");
      scheduledTask.addProperty(prop);
    }
    return scheduledTask;
  }
  @Override
  public ScheduledServiceMonthlyResource getTaskScheduled() {
    if (scheduledTask == null) {
      scheduledTask = new ScheduledServiceMonthlyResource();
      scheduledTask.setEnabled(true);
      scheduledTask.setId(null);
      scheduledTask.setName("taskMonthly");
      scheduledTask.setSchedule("monthly");
      // A future date
      Date startDate = DateUtils.addDays(new Date(), 10);
      startDate = DateUtils.round(startDate, Calendar.DAY_OF_MONTH);
      scheduledTask.setStartDate(String.valueOf(startDate.getTime()));
      scheduledTask.setRecurringTime("03:30");
      scheduledTask.setRecurringDay(Arrays.asList(new String[] {"1", "9", "17", "25"}));

      scheduledTask.setTypeId(UpdateIndexTaskDescriptor.ID);

      ScheduledServicePropertyResource prop = new ScheduledServicePropertyResource();
      prop.setKey("repositoryId");
      prop.setValue("all_repo");
      scheduledTask.addProperty(prop);
    }
    return scheduledTask;
  }
  @Test
  public void expireAllRepos() throws Exception {
    ScheduledServicePropertyResource prop = new ScheduledServicePropertyResource();
    prop.setKey("repositoryId");
    prop.setValue("all_repo");

    ScheduledServicePropertyResource age = new ScheduledServicePropertyResource();
    age.setKey("evictOlderCacheItemsThen");
    age.setValue(String.valueOf(10));

    TaskScheduleUtil.runTask(EvictUnusedItemsTaskDescriptor.ID, prop, age);
  }
  @Test
  @Ignore("Test is unstable - needs to be rewritten or replaced. See NEXUS-4606")
  public void doConcurrence() throws Exception {
    List<Thread> threads = new ArrayList<Thread>();
    final Map<Thread, Throwable> errors = new LinkedHashMap<Thread, Throwable>();
    for (final File f : files) {
      Thread t =
          new Thread(
              new Runnable() {

                public void run() {
                  try {
                    Verifier v =
                        MavenDeployer.deployAndGetVerifier(
                            GavUtil.newGav("nexus2497", "concurrence", "1.0-SNAPSHOT"),
                            getRepositoryUrl(REPO_TEST_HARNESS_SNAPSHOT_REPO),
                            f,
                            getOverridableFile("settings.xml"));

                    v.verifyErrorFreeLog();
                  } catch (Exception e) {
                    throw new RuntimeException(e);
                  }
                }
              });
      t.setUncaughtExceptionHandler(
          new UncaughtExceptionHandler() {
            public void uncaughtException(Thread t, Throwable e) {
              errors.put(t, e);
            }
          });

      threads.add(t);
    }

    ScheduledServicePropertyResource repo = new ScheduledServicePropertyResource();
    repo.setKey("repositoryId");
    repo.setValue(REPO_TEST_HARNESS_SNAPSHOT_REPO);
    TaskScheduleUtil.runTask(TASK_NAME, RebuildMavenMetadataTaskDescriptor.ID, repo);

    // uploads while rebuilding
    for (Thread thread : threads) {
      thread.start();
      Thread.yield();
    }

    // w8 for uploads
    for (Thread thread : threads) {
      thread.join();
    }

    TaskScheduleUtil.waitForAllTasksToStop(RebuildMavenMetadataTask.class);

    if (!errors.isEmpty()) {
      Set<Entry<Thread, Throwable>> entries = errors.entrySet();
      ByteArrayOutputStream str = new ByteArrayOutputStream();
      PrintStream s = new PrintStream(str);
      for (Entry<Thread, Throwable> entry : entries) {
        s.append(entry.getKey().getName());
        s.append("\n");
        entry.getValue().printStackTrace(s);
        s.append("\n");
        s.append("\n");
      }

      Assert.fail("Found some errors deploying:\n" + str.toString());
    }
    Assert.assertEquals(TaskScheduleUtil.getStatus(TASK_NAME), "Ok");
  }
  protected void createSnapshotTask(String name) throws Exception {
    ScheduledServicePropertyResource repositoryProp = new ScheduledServicePropertyResource();
    repositoryProp.setKey("repositoryId");
    repositoryProp.setValue("nexus-test-harness-snapshot-repo");

    ScheduledServicePropertyResource keepSnapshotsProp = new ScheduledServicePropertyResource();
    keepSnapshotsProp.setKey("minSnapshotsToKeep");
    keepSnapshotsProp.setValue(String.valueOf(0));

    ScheduledServicePropertyResource ageProp = new ScheduledServicePropertyResource();
    ageProp.setKey("removeOlderThanDays");
    ageProp.setValue(String.valueOf(0));

    ScheduledServicePropertyResource removeReleasedProp = new ScheduledServicePropertyResource();
    removeReleasedProp.setKey("removeIfReleaseExists");
    removeReleasedProp.setValue(String.valueOf(true));

    ScheduledServiceBaseResource scheduledTask = new ScheduledServiceBaseResource();
    scheduledTask.setEnabled(true);
    scheduledTask.setId(null);
    scheduledTask.setName(name);
    scheduledTask.setTypeId(SnapshotRemovalTaskDescriptor.ID);
    scheduledTask.setSchedule("manual");
    scheduledTask.addProperty(repositoryProp);
    scheduledTask.addProperty(keepSnapshotsProp);
    scheduledTask.addProperty(ageProp);
    scheduledTask.addProperty(removeReleasedProp);

    Status status = TaskScheduleUtil.create(scheduledTask);

    Assert.assertTrue(status.isSuccess());
  }
  @Test
  public void testSnapRepoDeployFilesRunTaskDeleteIFRelease() throws IOException, Exception {

    // create a snapshot repository
    createSnapshotRepo(snapRepoId);

    // add some artifacts
    copyToSnapRepo(snapRepoId);

    TaskScheduleUtil.waitForAllTasksToStop();

    // update indexes for search
    RepositoryMessageUtil.updateIndexes(snapRepoId);

    TaskScheduleUtil.waitForAllTasksToStop();

    // set Remover task parameters 2 latest version snapshots should be left over
    ScheduledServicePropertyResource keepSnapshotsProp = new ScheduledServicePropertyResource();
    keepSnapshotsProp.setKey(IVYSnapshotRemovalTaskDescriptor.MIN_TO_KEEP_FIELD_ID);
    keepSnapshotsProp.setValue(String.valueOf(2));

    ScheduledServicePropertyResource ageProp = new ScheduledServicePropertyResource();
    ageProp.setKey(IVYSnapshotRemovalTaskDescriptor.KEEP_DAYS_FIELD_ID);
    ageProp.setValue(String.valueOf(0));

    // and if a release version exists it should be removed too
    ScheduledServicePropertyResource relProp = new ScheduledServicePropertyResource();
    relProp.setKey(IVYSnapshotRemovalTaskDescriptor.REMOVE_WHEN_RELEASED_FIELD_ID);
    relProp.setValue(Boolean.toString(true));

    ScheduledServicePropertyResource repos = new ScheduledServicePropertyResource();
    repos.setKey("IvyRepositoryId");
    repos.setValue(snapRepoId);
    TaskScheduleUtil.runTask(
        "IvySnapshotRemoval",
        IVYSnapshotRemovalTaskDescriptor.ID,
        repos,
        keepSnapshotsProp,
        ageProp,
        relProp);

    TaskScheduleUtil.waitForAllTasksToStop();
    getEventInspectorsUtil().waitForCalmPeriod();

    // firstly assert that there is the artifact "auth-api" version "0.8-102" left over with
    // ".source.jar" and ".jar"
    Gav gav = GavUtil.newGav("ivyRemover", "auth-api", "0.8-102");

    List<NexusArtifact> result = getSearchMessageUtil().searchForGav(gav, snapRepoId);

    Assert.assertEquals(
        result.size(), 2, "Results: \n" + XStreamFactory.getXmlXStream().toXML(result));

    // secondly assert that there is the artifact "auth-api" version "0.8-103" left over with
    // ".source.jar" and ".jar"
    gav = GavUtil.newGav("ivyRemover", "auth-api", "0.8-103");

    result = getSearchMessageUtil().searchForGav(gav, snapRepoId);
    Assert.assertEquals(
        result.size(), 2, "Results: \n" + XStreamFactory.getXmlXStream().toXML(result));

    // thirdly assert that there isn't the artifact "auth-mod" version "0.8-102" left over
    gav = GavUtil.newGav("ivyRemover", "auth-mod", "1.0-102");

    result = getSearchMessageUtil().searchForGav(gav, snapRepoId);
    Assert.assertEquals(
        result.size(), 0, "Results: \n" + XStreamFactory.getXmlXStream().toXML(result));

    // fourthly assert that there isn't the artifact "auth-api" version "0.8-103" left over
    gav = GavUtil.newGav("ivyRemover", "auth-mod", "1.0-103");

    result = getSearchMessageUtil().searchForGav(gav, snapRepoId);
    Assert.assertEquals(
        result.size(), 0, "Results: \n" + XStreamFactory.getXmlXStream().toXML(result));

    // fifthly assert that there are at least 2 of 8 snapshots with 2 jar files in the whole test
    // group, 6 removed
    result =
        getSearchMessageUtil().searchFor(Collections.singletonMap("q", "ivyRemover"), snapRepoId);
    Assert.assertEquals(
        result.size(), 4, "Results: \n" + XStreamFactory.getXmlXStream().toXML(result));
  }