/**
   * Test deployment of an RHQ bundle recipe where the deploy directory is not to be fully managed.
   */
  @Test(enabled = true)
  public void testAntBundleNoManageRootDir() throws Exception {
    ResourceType resourceType =
        new ResourceType("testNoManageRootDirBundle", "plugin", ResourceCategory.SERVER, null);
    BundleType bundleType = new BundleType("testNoManageRootDirBundle", resourceType);
    Repo repo = new Repo("testNoManageRootDirBundle");
    PackageType packageType = new PackageType("testNoManageRootDirBundle", resourceType);
    Bundle bundle = new Bundle("testNoManageRootDirBundle", bundleType, repo, packageType);
    BundleVersion bundleVersion =
        new BundleVersion(
            "testNoManageRootDirBundle",
            "1.0",
            bundle,
            getRecipeFromFile("test-bundle-no-manage-root-dir.xml"));
    BundleDestination destination =
        new BundleDestination(
            bundle,
            "testNoManageRootDirBundle",
            new ResourceGroup("testNoManageRootDirBundle"),
            DEST_BASE_DIR_NAME,
            this.destDir.getAbsolutePath());
    Configuration config = new Configuration();

    BundleDeployment deployment = new BundleDeployment();
    deployment.setName("test bundle deployment name");
    deployment.setBundleVersion(bundleVersion);
    deployment.setConfiguration(config);
    deployment.setDestination(destination);

    // create bundle test files
    File file0 = new File(this.bundleFilesDir, "zero.properties");
    Properties props = new Properties();
    props.setProperty("zero", "0");
    FileOutputStream outputStream = new FileOutputStream(file0);
    props.store(outputStream, "zero file");
    outputStream.close();

    File file1 = new File(this.bundleFilesDir, "one.properties");
    props.clear();
    props.setProperty("one", "1");
    outputStream = new FileOutputStream(file1);
    props.store(outputStream, "one file");
    outputStream.close();

    File file2 = new File(this.bundleFilesDir, "two.properties");
    props.clear();
    props.setProperty("two", "2");
    outputStream = new FileOutputStream(file2);
    props.store(outputStream, "two file");
    outputStream.close();

    // create some external test files that don't belong to the bundle but are in the dest dir
    // (which is not fully managed by the bundle)
    this.destDir.mkdirs();
    File external1 = new File(this.destDir, "external1.properties");
    props.clear();
    props.setProperty("external1", "1");
    outputStream = new FileOutputStream(external1);
    props.store(outputStream, "external1 file");
    outputStream.close();

    File external2 = new File(this.destDir, "extdir/external2.properties");
    external2.getParentFile().mkdirs();
    props.clear();
    props.setProperty("external2", "2");
    outputStream = new FileOutputStream(external2);
    props.store(outputStream, "external2 file");
    outputStream.close();

    // deploy the bundle
    BundleDeployRequest request = new BundleDeployRequest();
    request.setBundleFilesLocation(this.bundleFilesDir);
    request.setResourceDeployment(new BundleResourceDeployment(deployment, null));
    request.setBundleManagerProvider(new MockBundleManagerProvider());
    request.setAbsoluteDestinationDirectory(this.destDir);

    BundleDeployResult results = plugin.deployBundle(request);

    assertResultsSuccess(results);

    // test that files were deployed in the proper place
    props.clear();
    loadProperties(props, new FileInputStream(new File(this.destDir, "zero.properties")));
    assert "0".equals(props.getProperty("zero")) : "did not deploy bundle correctly 0";
    loadProperties(props, new FileInputStream(new File(this.destDir, "subdir1/one.properties")));
    assert "1".equals(props.getProperty("one")) : "did not deploy bundle correctly 1";
    loadProperties(props, new FileInputStream(new File(this.destDir, "subdir2/two.properties")));
    assert "2".equals(props.getProperty("two")) : "did not deploy bundle correctly 2";

    DeploymentsMetadata metadata = new DeploymentsMetadata(this.destDir);
    assert metadata.isManaged() == true : "missing metadata directory";
    assert metadata.getCurrentDeploymentProperties().getManageRootDir() == false
        : "should not be managing root dir";

    // make sure our unmanaged files/directories weren't removed
    props.clear();
    loadProperties(props, new FileInputStream(new File(this.destDir, "external1.properties")));
    assert "1".equals(props.getProperty("external1"))
        : "bundle deployment removed our unmanaged file 1";
    loadProperties(
        props, new FileInputStream(new File(this.destDir, "extdir/external2.properties")));
    assert "2".equals(props.getProperty("external2"))
        : "bundle deployment removed our unmanaged file 2";

    // now purge the bundle - this should only purge those files that were laid down by the bundle
    // plus the metadata directory
    BundlePurgeRequest purgeRequest = new BundlePurgeRequest();
    purgeRequest.setLiveResourceDeployment(new BundleResourceDeployment(deployment, null));
    purgeRequest.setBundleManagerProvider(new MockBundleManagerProvider());
    purgeRequest.setAbsoluteDestinationDirectory(this.destDir);

    BundlePurgeResult purgeResults = plugin.purgeBundle(purgeRequest);
    assertResultsSuccess(purgeResults);

    // make sure our bundle files have been completely purged; the metadata directory should have
    // been purged too
    assert new File(this.destDir, "zero.properties").exists() == false;
    assert new File(this.destDir, "subdir1/one.properties").exists() == false;
    assert new File(this.destDir, "subdir2/two.properties").exists() == false;
    assert new File(this.destDir, "subdir1").exists() == false;
    assert new File(this.destDir, "subdir2").exists() == false;
    assert this.destDir.exists() == true
        : "deploy dir should still exist, we were told not to fully manage it";

    metadata = new DeploymentsMetadata(this.destDir);
    assert metadata.getMetadataDirectory().exists() == false
        : "metadata directory should not exist";

    // make sure our external, unmanaged files still exist - the purge should not have deleted these
    props.clear();
    loadProperties(props, new FileInputStream(new File(this.destDir, "external1.properties")));
    assert "1".equals(props.getProperty("external1")) : "bundle purge removed our unmanaged file 1";
    loadProperties(
        props, new FileInputStream(new File(this.destDir, "extdir/external2.properties")));
    assert "2".equals(props.getProperty("external2")) : "bundle purge removed our unmanaged file 2";
  }
Example #2
0
  @Override
  public BundlePurgeResponse purge(BundlePurgeRequest request) {
    final BundlePurgeResponse response = new BundlePurgeResponse();

    try {
      final BundleResourceDeployment resourceDeployment = request.getLiveBundleResourceDeployment();
      final BundleDeployment bundleDeployment = resourceDeployment.getBundleDeployment();

      // find the resource that will purge the bundle
      InventoryManager im = getInventoryManager();
      BundleType bundleType = bundleDeployment.getBundleVersion().getBundle().getBundleType();
      ResourceType resourceType = bundleType.getResourceType();
      Set<Resource> resources = im.getResourcesWithType(resourceType);
      if (resources.isEmpty()) {
        throw new Exception("No bundle plugin supports bundle type [" + bundleType + "]");
      }
      final int bundleHandlerResourceId = resources.iterator().next().getId();
      final ResourceContainer resourceContainer = im.getResourceContainer(bundleHandlerResourceId);
      if (null == resourceContainer.getResourceContext()) {
        throw new Exception(
            "No bundle plugin resource available to handle purge for bundle type ["
                + bundleType
                + "]. Ensure the bundle plugin is deployed and its resource is imported into inventory.");
      }

      // purge the bundle utilizing the bundle facet object
      String deploymentMessage =
          "Deployment ["
              + bundleDeployment
              + "] to be purged via ["
              + resourceDeployment.getResource()
              + "]";
      auditDeployment(
          resourceDeployment, AUDIT_PURGE_STARTED, bundleDeployment.getName(), deploymentMessage);

      File absoluteDestDir = getAbsoluteDestinationDir(request.getLiveBundleResourceDeployment());

      org.rhq.core.pluginapi.bundle.BundlePurgeRequest purgeRequest =
          new org.rhq.core.pluginapi.bundle.BundlePurgeRequest();
      purgeRequest.setBundleManagerProvider(this);
      purgeRequest.setLiveResourceDeployment(resourceDeployment);
      purgeRequest.setAbsoluteDestinationDirectory(absoluteDestDir);

      // get the bundle facet object that will process the bundle and call it to start the purge
      int facetMethodTimeout =
          30 * 60
              * 1000; // 30 minutes should be enough time for the bundle plugin to purge everything
      BundleFacet bundlePluginComponent =
          getBundleFacet(bundleHandlerResourceId, facetMethodTimeout);
      BundlePurgeResult result = bundlePluginComponent.purgeBundle(purgeRequest);
      if (result.isSuccess()) {
        auditDeployment(
            resourceDeployment, AUDIT_PURGE_ENDED, bundleDeployment.getName(), deploymentMessage);
      } else {
        response.setErrorMessage(result.getErrorMessage());
        auditDeployment(
            resourceDeployment,
            AUDIT_PURGE_ENDED,
            bundleDeployment.getName(),
            null,
            Status.FAILURE,
            "Failed: " + deploymentMessage,
            result.getErrorMessage());
      }
    } catch (Throwable t) {
      log.error("Failed to purge bundle: " + request, t);
      response.setErrorMessage(t);
    }

    return response;
  }