/**
  * Handle a BackendFailureException or an exception thrown from a backend query/action and
  * re-throw as a WebApplicationException.
  *
  * <p>If the exception indicates that the referenced backend entity does not exist
  * and @notFoundAs404 is true, then throw a WebApplicationException which wraps a 404 HTTP
  * response.
  *
  * @param clz dummy explicit type parameter for use when type inference is not possible
  *     (irrelevant in any case as a value is never returned, rather an exception is always thrown)
  * @param e the exception to handle
  * @param notFoundAs404 whether to return a 404 if appropriate
  * @returns the result of the operation
  */
 protected <T> T handleError(Class<T> clz, Exception e, boolean notFoundAs404) {
   if ((e instanceof EntityNotFoundException) && (notFoundAs404)) {
     throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND).build());
   } else if ((e instanceof BackendFailureException)
       && (!StringHelper.isNullOrEmpty(e.getMessage()))) {
     LOG.errorFormat(localize(Messages.BACKEND_FAILED_TEMPLATE), e.getMessage(), null);
     throw new WebFaultException(null, e.getMessage(), Response.Status.BAD_REQUEST);
   } else {
     LOG.errorFormat(localize(Messages.BACKEND_FAILED_TEMPLATE), detail(e), e);
     throw new WebFaultException(e, detail(e), Response.Status.INTERNAL_SERVER_ERROR);
   }
 }
예제 #2
0
  /**
   * Prepares the monitoring objects for the command by the default behavior:
   *
   * <ul>
   *   <li>{@link ExecutionContext} determines how the command should be monitored. By default,
   *       non-internal commands will be associated with {@code Job} to represent the command
   *       execution. Internal commands will not be monitored by default, therefore the {@code
   *       ExecutionContext} is created as non-monitored context.
   *   <li>{@link Job} is created for monitored actions
   * </ul>
   *
   * @param command The created instance of the command (can't be <code>null</code>).
   * @param actionType The action type of the command
   * @param runAsInternal Indicates if the command should be run as internal action or not
   * @param hasCorrelationId Indicates if the current command was executed under a correlation-ID
   */
  public static void prepareCommandForMonitoring(
      CommandBase<?> command, VdcActionType actionType, boolean runAsInternal) {

    ExecutionContext context = command.getExecutionContext();
    if (context == null) {
      context = new ExecutionContext();
    }

    try {
      boolean isMonitored = shouldMonitorCommand(actionType, runAsInternal);

      // A monitored job is created for monitored external flows
      if (isMonitored || context.isJobRequired()) {
        Job job = getJob(command, actionType);
        context.setExecutionMethod(ExecutionMethod.AsJob);
        context.setJob(job);
        command.setExecutionContext(context);
        command.setJobId(job.getId());
        context.setMonitored(true);
      }
    } catch (Exception e) {
      log.errorFormat(
          "Failed to prepare command of type {0} for monitoring due to error {1}",
          actionType.name(), ExceptionUtils.getMessage(e), e);
    }
  }
예제 #3
0
 private static void endJob(boolean exitStatus, Job job) {
   job.markJobEnded(exitStatus);
   try {
     JobRepositoryFactory.getJobRepository().updateCompletedJobAndSteps(job);
   } catch (Exception e) {
     log.errorFormat("Failed to end Job {0}, {1}", job.getId(), job.getActionType().name(), e);
   }
 }
예제 #4
0
 /**
  * Updates the step with the id in the external system in which the describe task runs.
  *
  * @param step The step which represents the external task
  * @param externalId The id of the task in the external system
  * @param systemType The type of the system
  */
 public static void updateStepExternalId(
     Step step, Guid externalId, ExternalSystemType systemType) {
   if (step != null) {
     step.getExternalSystem().setId(externalId);
     step.getExternalSystem().setType(systemType);
     try {
       JobRepositoryFactory.getJobRepository().updateStep(step);
     } catch (Exception e) {
       log.errorFormat(
           "Failed to save step {0}, {1} for system-type {2} with id {3}",
           step.getId(), step.getStepType().name(), systemType.name(), externalId, e);
     }
   }
 }
예제 #5
0
  /**
   * Finalizes a {@code Step} execution which represents a VDSM task. In case of a failure status,
   * the job will not be marked as failed at this stage, but via executing the {@code
   * CommandBase.endAction} with the proper status by {@code the AsyncTaskManager}.
   *
   * @param stepId A unique identifier of the step to finalize.
   * @param exitStatus The status which the step should be ended with.
   */
  public static void endTaskStep(Guid stepId, JobExecutionStatus exitStatus) {
    try {
      if (stepId != null) {
        Step step = JobRepositoryFactory.getJobRepository().getStep(stepId);

        if (step != null) {
          step.markStepEnded(exitStatus);
          JobRepositoryFactory.getJobRepository().updateStep(step);
        }
      }
    } catch (Exception e) {
      log.errorFormat("Failed to terminate step {0} with status {1}", stepId, exitStatus, e);
    }
  }
  /**
   * Adds a pair of {@code Enum} and message to the messages map. If the key is not valid, an error
   * message is logged. The key should be resolvable as an {@code Enum}, once its prefix is trimmed
   * and the searched for an {@code Enum} match by name. Possible entries of (key,value) from the
   * resource bundle:
   *
   * <pre>
   * job.ChangeVMCluster=Change VM ${VM} Cluster to ${VdsGroups}
   * step.VALIDATING=Validating
   * </pre>
   *
   * @param key The key of the pair to be added, by which the enum is searched.
   * @param value The message of the pair to be added
   * @param enumClass The enum class search for an instance which match the key
   * @param messagesMap The map whic the message should be added to
   * @param prefixLength The length of the key prefix
   */
  private <T extends Enum<T>> void addMessage(
      String key, String value, Map<T, String> messagesMap, Class<T> enumClass, int prefixLength) {

    T enumKey = null;

    try {
      enumKey = T.valueOf(enumClass, key.substring(prefixLength));
    } catch (IllegalArgumentException e) {
      log.errorFormat("Message key {0} is not valid for enum {1}", key, enumClass.getSimpleName());
      return;
    }

    if (!messagesMap.containsKey(key)) {
      messagesMap.put(enumKey, value);
    } else {
      log.warnFormat(
          "Code {0} appears more then once in {1} table.", key, enumClass.getSimpleName());
    }
  }
  /**
   * Load resources files and initialize the messages cache.
   *
   * @param bundleBaseName The base name of the resource bundle
   */
  public void initialize(String bundleBaseName) {
    ResourceBundle bundle = ResourceBundle.getBundle(bundleBaseName);
    final int jobMessagePrefixLength = JOB_MESSAGE_PREFIX.length();
    final int stepMessagePrefixLength = STEP_MESSAGE_PREFIX.length();

    for (String key : bundle.keySet()) {

      if (key.startsWith(JOB_MESSAGE_PREFIX)) {
        addMessage(
            key, bundle.getString(key), jobMessages, VdcActionType.class, jobMessagePrefixLength);
      } else if (key.startsWith(STEP_MESSAGE_PREFIX)) {
        addMessage(
            key, bundle.getString(key), stepMessages, StepEnum.class, stepMessagePrefixLength);
      } else {
        log.errorFormat(
            "The message key {0} cannot be categorized since not started with {1} nor {2}",
            key, JOB_MESSAGE_PREFIX, STEP_MESSAGE_PREFIX);
      }
    }
  }
예제 #8
0
  private static Step addSubStep(Step parentStep, StepEnum stepName, String description) {
    Step step = null;

    if (parentStep != null) {
      if (description == null) {
        description = ExecutionMessageDirector.getInstance().getStepMessage(stepName);
      }
      step = parentStep.addStep(stepName, description);

      try {
        JobRepositoryFactory.getJobRepository().saveStep(step);
      } catch (Exception e) {
        log.errorFormat(
            "Failed to save new step {0} for step {1}, {2}.",
            stepName.name(), parentStep.getId(), parentStep.getStepType().name(), e);
        parentStep.getSteps().remove(step);
        step = null;
      }
    }
    return step;
  }
예제 #9
0
  /**
   * Adds a {@link Step} entity by the provided context. A {@link Step} will not be created if
   * {@code ExecutionContext.isMonitored()} returns false.
   *
   * @param context The context of the execution which defines visibility and execution method.
   * @param stepName The name of the step.
   * @param description A presentation name for the step. If not provided, the presentation name is
   *     resolved by the {@code stepName}.
   * @param isExternal Indicates if the step is invoked by a plug-in
   * @return
   */
  public static Step addStep(
      ExecutionContext context, StepEnum stepName, String description, boolean isExternal) {
    if (context == null) {
      return null;
    }
    Step step = null;

    if (context.isMonitored()) {
      if (description == null) {
        description = ExecutionMessageDirector.getInstance().getStepMessage(stepName);
      }

      try {
        Job job = context.getJob();
        if (context.getExecutionMethod() == ExecutionMethod.AsJob && job != null) {
          step = job.addStep(stepName, description);
          try {
            step.setExternal(isExternal);
            JobRepositoryFactory.getJobRepository().saveStep(step);
          } catch (Exception e) {
            log.errorFormat(
                "Failed to save new step {0} for job {1}, {2}.",
                stepName.name(), job.getId(), job.getActionType().name(), e);
            job.getSteps().remove(step);
            step = null;
          }
        } else {
          Step contextStep = context.getStep();
          if (context.getExecutionMethod() == ExecutionMethod.AsStep && contextStep != null) {
            step = addSubStep(contextStep, stepName, description);
            step.setExternal(isExternal);
          }
        }
      } catch (Exception e) {
        log.error(e);
      }
    }
    return step;
  }
  /**
   * Update the given VM with the (static) data that is contained in the configuration. The {@link
   * VM#getImages()} will contain the images that were read from the configuration.
   *
   * @param vm The VM to update.
   * @param configuration The configuration to update from.
   * @return In case of a problem reading the configuration, <code>false</code>. Otherwise, <code>
   *     true</code>.
   */
  public boolean updateVmFromConfiguration(VM vm, String configuration) {

    try {
      VmStatic oldVmStatic = vm.getStaticData();
      RefObject<VM> vmRef = new RefObject<VM>();
      RefObject<ArrayList<DiskImage>> imagesRef = new RefObject<ArrayList<DiskImage>>();
      RefObject<ArrayList<VmNetworkInterface>> interfacesRef =
          new RefObject<ArrayList<VmNetworkInterface>>();
      new OvfManager().ImportVm(configuration, vmRef, imagesRef, interfacesRef);
      new VMStaticOvfLogHandler(vmRef.argvalue.getStaticData()).resetDefaults(oldVmStatic);

      vm.setStaticData(vmRef.argvalue.getStaticData());
      vm.setImages(imagesRef.argvalue);
      vm.setInterfaces(interfacesRef.argvalue);

      // These fields are not saved in the OVF, so get them from the current VM.
      vm.setdedicated_vm_for_vds(oldVmStatic.getdedicated_vm_for_vds());
      vm.setiso_path(oldVmStatic.getiso_path());
      vm.setvds_group_id(oldVmStatic.getvds_group_id());
      // The VM configuration does not hold the vds group Id.
      // It is necessary to fetch the vm static from the Db, in order to get this information
      VmStatic vmStaticFromDb = getVmStaticDao().get(vm.getId());
      if (vmStaticFromDb != null) {
        VDSGroup vdsGroup = getVdsGroupDao().get(vmStaticFromDb.getvds_group_id());
        if (vdsGroup != null) {
          vm.setvds_group_compatibility_version(vdsGroup.getcompatibility_version());
          vm.setvds_group_name(vdsGroup.getname());
          vm.setvds_group_cpu_name(vdsGroup.getcpu_name());
        }
      }
      return true;
    } catch (OvfReaderException e) {
      log.errorFormat("Failed to update VM from the configuration: {0}).", configuration, e);
      return false;
    }
  }
예제 #11
0
  public static List<DbUser> sync(List<DbUser> dbUsers) {
    List<DbUser> usersToUpdate = new ArrayList<>();
    Map<String, Map<String, Set<String>>> authzToNamespaceToUserIds = new HashMap<>();
    Map<String, List<DbUser>> dbUsersPerAuthz = new HashMap<>();

    // Initialize the entries based on authz in the map
    for (DbUser dbUser : dbUsers) {
      MultiValueMapUtils.addToMap(dbUser.getDomain(), dbUser, dbUsersPerAuthz);
      if (!authzToNamespaceToUserIds.containsKey(dbUser.getDomain())) {
        authzToNamespaceToUserIds.put(dbUser.getDomain(), new HashMap<String, Set<String>>());
      }
      MultiValueMapUtils.addToMapOfSets(
          dbUser.getNamespace(),
          dbUser.getExternalId(),
          authzToNamespaceToUserIds.get(dbUser.getDomain()));
    }

    for (Entry<String, Map<String, Set<String>>> entry : authzToNamespaceToUserIds.entrySet()) {
      Map<String, DbUser> activeUsers = new HashMap<>();
      String authz = entry.getKey();
      try {
        ExtensionProxy authzExtension =
            EngineExtensionsManager.getInstance().getExtensionByName(authz);
        for (Entry<String, Set<String>> userIdsPerNamespace : entry.getValue().entrySet()) {
          for (ExtMap principal :
              AuthzUtils.fetchPrincipalsByIdsRecursively(
                  authzExtension, userIdsPerNamespace.getKey(), userIdsPerNamespace.getValue())) {
            DirectoryUtils.flatGroups(principal);
            DbUser dbUser = DirectoryUtils.mapPrincipalRecordToDbUser(authz, principal);
            dbUser.setGroupIds(DirectoryUtils.getGroupIdsFromPrincipal(authz, principal));
            activeUsers.put(dbUser.getExternalId(), dbUser);
          }
        }

        for (DbUser dbUser : dbUsersPerAuthz.get(authz)) {
          DbUser activeUser = activeUsers.get(dbUser.getExternalId());
          if (activeUser != null) {
            if (!activeUser.equals(dbUser)) {
              activeUser.setId(dbUser.getId());
              activeUser.setAdmin(dbUser.isAdmin());
              log.infoFormat(
                  "Principal {0}::{1} synchronized",
                  activeUser.getLoginName(), activeUser.getDomain());
              usersToUpdate.add(activeUser);
            }
          } else {
            log.infoFormat(
                "Deactivating non existing principal {0}::{1}",
                dbUser.getLoginName(), dbUser.getDomain());
            dbUser.setActive(false);
            usersToUpdate.add(dbUser);
          }
        }
      } catch (Exception ex) {
        log.errorFormat(
            "Error during user synchronization of extension {0}. Exception message is {1}",
            authz, ex.getMessage());
        log.debug("", ex);
      }
    }
    return usersToUpdate;
  }