private void audit(String action, BundleResourceDeploymentHistory.Status status, String message) {
   try {
     bundleManagerProvider.auditDeployment(
         bundleResourceDeployment, action, "recipe", null, status, message, null);
     if (log.isDebugEnabled()) {
       log.debug(
           "Deployment ["
               + bundleResourceDeployment.getBundleDeployment().getBundleVersion()
               + "] audit: action=["
               + action
               + "], status=["
               + status
               + "], message: "
               + message);
     }
   } catch (Exception e) {
     log.warn(
         "Failed to send audit message for deployment of ["
             + bundleResourceDeployment.getBundleDeployment().getBundleVersion()
             + "]. audit action=["
             + action
             + "], status=["
             + status
             + "], message: "
             + message);
   }
 }
예제 #2
0
 private void completeDeployment(
     BundleResourceDeployment resourceDeployment, BundleDeploymentStatus status, String message) {
   getBundleServerService().setBundleDeploymentStatus(resourceDeployment.getId(), status);
   BundleResourceDeploymentHistory.Status auditStatus =
       BundleDeploymentStatus.SUCCESS.equals(status)
           ? BundleResourceDeploymentHistory.Status.SUCCESS
           : BundleResourceDeploymentHistory.Status.FAILURE;
   auditDeployment(
       resourceDeployment,
       AUDIT_DEPLOYMENT_ENDED,
       resourceDeployment.getBundleDeployment().getName(),
       null,
       auditStatus,
       message,
       null);
 }
예제 #3
0
  public void auditDeployment(
      BundleResourceDeployment bundleResourceDeployment,
      String action,
      String info,
      BundleResourceDeploymentHistory.Category category,
      BundleResourceDeploymentHistory.Status status,
      String message,
      String attachment) {
    if (null == action || null == info) {
      throw new IllegalArgumentException("action or info is null");
    }

    if (null == status) {
      status = BundleResourceDeploymentHistory.Status.SUCCESS;
    }
    BundleResourceDeploymentHistory history =
        new BundleResourceDeploymentHistory(
            "Bundle Plugin", action, info, category, status, message, attachment);
    log.debug("Reporting deployment step [" + history + "] to Server...");
    getBundleServerService().addDeploymentHistory(bundleResourceDeployment.getId(), history);
  }
예제 #4
0
  /**
   * Given a deployment, this examines the destination and the resource to determine where exactly
   * the bundle distribution should be written.
   *
   * @param bundleResourceDeployment describes where the bundle should be or is deployed
   * @return absolute directory location where the bundle should be deployed
   */
  private File getAbsoluteDestinationDir(BundleResourceDeployment bundleResourceDeployment) {
    BundleDestination dest = bundleResourceDeployment.getBundleDeployment().getDestination();
    String destBaseDirName = dest.getDestinationBaseDirectoryName();
    String relativeDeployDir = dest.getDeployDir();

    // paranoia, if no deploy dir is given, as assume it will be directly under the base location
    if (relativeDeployDir == null || relativeDeployDir.trim().length() == 0) {
      relativeDeployDir = File.separator;
    }

    // get the resource entity stored in our local inventory
    InventoryManager im = getInventoryManager();
    Resource resource = bundleResourceDeployment.getResource();
    ResourceContainer container = im.getResourceContainer(resource);
    resource = container.getResource();

    // find out the type of base location that is specified by the bundle destination
    BundleDestinationBaseDirectory bundleDestBaseDir = null;
    ResourceTypeBundleConfiguration rtbc =
        resource.getResourceType().getResourceTypeBundleConfiguration();
    if (rtbc == null) {
      throw new IllegalArgumentException(
          "The resource type doesn't support bundle deployments: " + resource);
    }
    for (BundleDestinationBaseDirectory bdbd : rtbc.getBundleDestinationBaseDirectories()) {
      if (bdbd.getName().equals(destBaseDirName)) {
        bundleDestBaseDir = bdbd;
        break;
      }
    }
    if (bundleDestBaseDir == null) {
      throw new IllegalArgumentException(
          "The resource type doesn't support bundle destination base location named ["
              + destBaseDirName
              + "]");
    }

    // based on the type of destination base location, determine the root base directory
    String destBaseDirValueName =
        bundleDestBaseDir.getValueName(); // the name we look up in the given context
    String baseLocation;
    switch (bundleDestBaseDir.getValueContext()) {
      case fileSystem:
        {
          if (!new File(relativeDeployDir).isAbsolute()) {
            // the deploy dir is not absolute; since we need to pin it to something, we assume the
            // top root directory
            // unless the descriptor told us to go somewhere else differently
            baseLocation = destBaseDirValueName; // ultimately this came from the plugin descriptor
            if (baseLocation == null || baseLocation.trim().length() == 0) {
              baseLocation =
                  File
                      .separator; // paranoia, if the plugin descriptor didn't specify, assume the
                                  // top root directory
            }
          } else {
            baseLocation = null; // so the relativeDeployDir is processed as an absolute dir
          }
          break;
        }
      case pluginConfiguration:
        {
          baseLocation =
              resource.getPluginConfiguration().getSimpleValue(destBaseDirValueName, null);
          if (baseLocation == null) {
            throw new IllegalArgumentException(
                "Cannot determine the bundle base deployment location - "
                    + "there is no plugin configuration setting for ["
                    + destBaseDirValueName
                    + "]");
          }
          break;
        }
      case resourceConfiguration:
        {
          baseLocation =
              resource.getResourceConfiguration().getSimpleValue(destBaseDirValueName, null);
          if (baseLocation == null) {
            throw new IllegalArgumentException(
                "Cannot determine the bundle base deployment location - "
                    + "there is no resource configuration setting for ["
                    + destBaseDirValueName
                    + "]");
          }
          break;
        }
      case measurementTrait:
        {
          baseLocation = getMeasurementManager().getTraitValue(container, destBaseDirValueName);
          if (baseLocation == null) {
            throw new IllegalArgumentException(
                "Cannot obtain trait ["
                    + destBaseDirName
                    + "] for resource ["
                    + resource.getName()
                    + "]");
          }
          break;
        }
      default:
        {
          throw new IllegalArgumentException(
              "Unknown bundle destination location context: " + bundleDestBaseDir);
        }
    }

    File destDir = new File(baseLocation, relativeDeployDir);

    if (!destDir.isAbsolute()) {
      throw new IllegalArgumentException(
          "The base location path specified by ["
              + destBaseDirValueName
              + "] in the context ["
              + bundleDestBaseDir.getValueContext()
              + "] along with the destination directory of ["
              + relativeDeployDir
              + "] did not resolve to an absolute path ["
              + destDir.getPath()
              + "] so there is no way to know where to put the bundle.");
    }

    return destDir;
  }
예제 #5
0
  /**
   * Downloads the bundle's files into the bundle plugin's tmp directory and returns that tmp
   * directory.
   *
   * @param resourceDeployment access to deployment information, including what bundle files need to
   *     be downloaded
   * @param downloadDir location where the bundle files should be downloaded
   * @return map of the package versions to their files that were downloaded
   * @throws Exception
   */
  private Map<PackageVersion, File> downloadBundleFiles(
      BundleResourceDeployment resourceDeployment, File downloadDir) throws Exception {

    BundleDeployment bundleDeployment = resourceDeployment.getBundleDeployment();
    BundleVersion bundleVersion = bundleDeployment.getBundleVersion();

    Map<PackageVersion, File> packageVersionFiles = new HashMap<PackageVersion, File>();
    List<PackageVersion> packageVersions = getAllBundleVersionPackageVersions(bundleVersion);
    for (PackageVersion packageVersion : packageVersions) {
      File packageFile = new File(downloadDir, packageVersion.getFileName());

      try {
        verifyHash(packageVersion, packageFile);
      } catch (Exception e) {

        // file either doesn't exist or it hash doesn't match, download a new copy
        packageFile.getParentFile().mkdirs();
        FileOutputStream fos = new FileOutputStream(packageFile);
        try {
          auditDeployment(
              resourceDeployment,
              AUDIT_FILE_DOWNLOAD_STARTED,
              packageVersion.getDisplayName(),
              "Downloading [" + packageVersion + "]");

          long size = getFileContent(packageVersion, fos);

          if (packageVersion.getFileSize() != null
              && size != packageVersion.getFileSize().longValue()) {
            String message =
                "Downloaded bundle file ["
                    + packageVersion
                    + "] but its size was ["
                    + size
                    + "] when it was expected to be ["
                    + packageVersion.getFileSize()
                    + "].";
            log.warn(message);
            auditDeployment(
                resourceDeployment,
                AUDIT_FILE_DOWNLOAD_ENDED,
                packageVersion.getDisplayName(),
                null,
                BundleResourceDeploymentHistory.Status.WARN,
                message,
                null);
          } else {
            auditDeployment(
                resourceDeployment,
                AUDIT_FILE_DOWNLOAD_ENDED,
                packageVersion.getDisplayName(),
                "Download complete for [" + packageVersion + "]");
          }
        } catch (Exception e2) {
          String message = "Failed to downloaded bundle file [" + packageVersion + "] " + e2;
          log.warn(message);
          auditDeployment(
              resourceDeployment,
              AUDIT_FILE_DOWNLOAD_ENDED,
              packageVersion.getDisplayName(),
              null,
              BundleResourceDeploymentHistory.Status.FAILURE,
              message,
              null);
        } finally {
          fos.close();
        }

        // now try to verify it again, if this throws an exception, that is very bad and we need to
        // abort
        verifyHash(packageVersion, packageFile);
      }

      packageVersionFiles.put(packageVersion, packageFile);
    }

    return packageVersionFiles;
  }
예제 #6
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;
  }
예제 #7
0
  @Override
  public BundleScheduleResponse schedule(final BundleScheduleRequest request) {
    final BundleScheduleResponse response = new BundleScheduleResponse();

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

      // find the resource that will handle the bundle processing
      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 deployment for bundle type ["
                + bundleType
                + "]. Ensure the bundle plugin is deployed and its resource is imported into inventory.");
      }

      auditDeployment(
          resourceDeployment,
          AUDIT_DEPLOYMENT_SCHEDULED,
          bundleDeployment.getName(),
          "Scheduled deployment time: " + request.getRequestedDeployTimeAsString());

      Runnable deployerRunnable =
          new Runnable() {
            public void run() {
              try {
                // pull down the bundle files that the plugin will need in order to process the
                // bundle
                File pluginTmpDir = resourceContainer.getResourceContext().getTemporaryDirectory();
                File bundleFilesDir =
                    new File(
                        pluginTmpDir,
                        "bundle-versions/" + bundleDeployment.getBundleVersion().getId());
                bundleFilesDir.mkdirs();

                // clean up any old downloads we may have retrieved before. This helps clean out
                // our temp directory so we don't unnecessarily fill up our file system with
                // obsolete files
                removeOldDownloadedBundleFiles(bundleFilesDir);

                // now download the bundle files we need for the current deployment
                Map<PackageVersion, File> downloadedFiles =
                    downloadBundleFiles(resourceDeployment, bundleFilesDir);

                // deploy the bundle utilizing the bundle facet object
                String deploymentMessage =
                    "Deployment ["
                        + bundleDeployment
                        + "] to ["
                        + resourceDeployment.getResource()
                        + "]";
                auditDeployment(
                    resourceDeployment,
                    AUDIT_DEPLOYMENT_STARTED,
                    bundleDeployment.getName(),
                    deploymentMessage);

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

                BundleDeployRequest deployRequest = new BundleDeployRequest();
                deployRequest.setBundleManagerProvider(BundleManager.this);
                deployRequest.setResourceDeployment(resourceDeployment);
                deployRequest.setBundleFilesLocation(bundleFilesDir);
                deployRequest.setPackageVersionFiles(downloadedFiles);
                deployRequest.setCleanDeployment(request.isCleanDeployment());
                deployRequest.setRevert(request.isRevert());
                deployRequest.setAbsoluteDestinationDirectory(absoluteDestDir);

                // get the bundle facet object that will process the bundle and call it to start the
                // deployment
                int facetMethodTimeout =
                    4 * 60 * 60 * 1000; // 4 hours is given to the bundle plugin to do its thing
                BundleFacet bundlePluginComponent =
                    getBundleFacet(bundleHandlerResourceId, facetMethodTimeout);
                BundleDeployResult result = bundlePluginComponent.deployBundle(deployRequest);
                if (result.isSuccess()) {
                  completeDeployment(
                      resourceDeployment, BundleDeploymentStatus.SUCCESS, deploymentMessage);
                } else {
                  completeDeployment(
                      resourceDeployment, BundleDeploymentStatus.FAILURE, result.getErrorMessage());
                }
              } catch (InterruptedException ie) {
                log.error("Failed to complete bundle deployment due to interrupt", ie);
                completeDeployment(
                    resourceDeployment, BundleDeploymentStatus.FAILURE, "Deployment interrupted");
              } catch (Throwable t) {
                log.error("Failed to complete bundle deployment", t);
                completeDeployment(
                    resourceDeployment,
                    BundleDeploymentStatus.FAILURE,
                    "Deployment failed: " + ThrowableUtil.getAllMessages(t));
              }
            }
          };

      this.deployerThreadPool.execute(deployerRunnable);
    } catch (Throwable t) {
      log.error("Failed to schedule bundle request: " + request, t);
      response.setErrorMessage(t);
    }

    return response;
  }