/** * 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); } }
/** * 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); } }
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); } }
/** * 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); } } }
/** * 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); } } }
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; }
/** * 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; } }
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; }