use of com.evolveum.midpoint.xml.ns._public.common.common_3.SystemConfigurationType in project midpoint by Evolveum.
the class SecurityHelper method locateSecurityPolicy.
/**
* Returns security policy applicable for the specified user. It looks for organization and global policies and takes into account
* deprecated properties and password policy references. The resulting security policy has all the (non-deprecated) properties set.
* If there is also referenced value policy, it is will be stored as "object" in the value policy reference inside the
* returned security policy.
*/
public <F extends FocusType> SecurityPolicyType locateSecurityPolicy(PrismObject<F> user, PrismObject<SystemConfigurationType> systemConfiguration, Task task, OperationResult result) throws SchemaException {
PrismObject<SecurityPolicyType> orgSecurityPolicy = objectResolver.searchOrgTreeWidthFirstReference(user, o -> o.asObjectable().getSecurityPolicyRef(), "security policy", task, result);
LOGGER.trace("Found organization security policy: {}", orgSecurityPolicy);
if (orgSecurityPolicy != null) {
SecurityPolicyType orgSecurityPolicyType = orgSecurityPolicy.asObjectable();
postProcessSecurityPolicy(orgSecurityPolicyType, task, result);
traceSecurityPolicy(orgSecurityPolicyType, user);
return orgSecurityPolicyType;
}
if (systemConfiguration != null) {
SecurityPolicyType globalSecurityPolicy = resolveGlobalSecurityPolicy(user, systemConfiguration.asObjectable(), task, result);
if (globalSecurityPolicy != null) {
return globalSecurityPolicy;
}
}
// DEPRECATED, legacy
PrismObject<ValuePolicyType> orgPasswordPolicy = objectResolver.searchOrgTreeWidthFirstReference(user, o -> o.asObjectable().getPasswordPolicyRef(), "security policy", task, result);
LOGGER.trace("Found organization password policy: {}", orgPasswordPolicy);
if (orgPasswordPolicy != null) {
SecurityPolicyType policy = postProcessPasswordPolicy(orgPasswordPolicy.asObjectable());
traceSecurityPolicy(policy, user);
return policy;
}
if (systemConfiguration != null) {
SecurityPolicyType globalPasswordPolicy = resolveGlobalPasswordPolicy(user, systemConfiguration.asObjectable(), task, result);
if (globalPasswordPolicy != null) {
return globalPasswordPolicy;
}
}
return null;
}
use of com.evolveum.midpoint.xml.ns._public.common.common_3.SystemConfigurationType in project midpoint by Evolveum.
the class SystemConfigurationTypeUtil method setEnableExperimentalCode.
public static void setEnableExperimentalCode(SystemConfigurationType s, Boolean enableExperimentalCode) {
if (enableExperimentalCode == null) {
if (s.getInternals() != null) {
s.getInternals().setEnableExperimentalCode(null);
s.asPrismContainerValue().findContainer(SystemConfigurationType.F_INTERNALS).normalize();
}
} else {
if (s.getInternals() == null) {
// hopefully prismContext etc is correctly set
s.setInternals(new InternalsConfigurationType());
}
s.getInternals().setEnableExperimentalCode(enableExperimentalCode);
}
}
use of com.evolveum.midpoint.xml.ns._public.common.common_3.SystemConfigurationType in project midpoint by Evolveum.
the class AbstractSearchIterativeTaskHandler method runInternal.
public TaskRunResult runInternal(Task coordinatorTask) {
OperationResult opResult = new OperationResult(taskOperationPrefix + ".run");
opResult.setStatus(OperationResultStatus.IN_PROGRESS);
TaskRunResult runResult = new TaskRunResult();
runResult.setOperationResult(opResult);
H resultHandler;
try {
resultHandler = createHandler(runResult, coordinatorTask, opResult);
} catch (SecurityViolationException | SchemaException | RuntimeException e) {
LOGGER.error("{}: Error while creating a result handler: {}", taskName, e.getMessage(), e);
opResult.recordFatalError("Error while creating a result handler: " + e.getMessage(), e);
runResult.setRunResultStatus(TaskRunResultStatus.PERMANENT_ERROR);
runResult.setProgress(coordinatorTask.getProgress());
return runResult;
}
if (resultHandler == null) {
// the error should already be in the runResult
return runResult;
}
// copying relevant configuration items from task to handler
resultHandler.setEnableIterationStatistics(isEnableIterationStatistics());
resultHandler.setEnableSynchronizationStatistics(isEnableSynchronizationStatistics());
resultHandler.setEnableActionsExecutedStatistics(isEnableActionsExecutedStatistics());
boolean cont = initializeRun(resultHandler, runResult, coordinatorTask, opResult);
if (!cont) {
return runResult;
}
// TODO: error checking - already running
if (coordinatorTask.getOid() == null) {
throw new IllegalArgumentException("Transient tasks cannot be run by " + AbstractSearchIterativeTaskHandler.class + ": " + coordinatorTask);
}
handlers.put(coordinatorTask.getOid(), resultHandler);
ObjectQuery query;
try {
query = createQuery(resultHandler, runResult, coordinatorTask, opResult);
} catch (SchemaException ex) {
logErrorAndSetResult(runResult, resultHandler, "Schema error while creating a search filter", ex, OperationResultStatus.FATAL_ERROR, TaskRunResultStatus.PERMANENT_ERROR);
return runResult;
}
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("{}: using a query (before evaluating expressions):\n{}", taskName, DebugUtil.debugDump(query));
}
if (query == null) {
// the error should already be in the runResult
return runResult;
}
try {
// TODO consider which variables should go here (there's no focus, shadow, resource - only configuration)
if (ExpressionUtil.hasExpressions(query.getFilter())) {
PrismObject<SystemConfigurationType> configuration = systemObjectCache.getSystemConfiguration(opResult);
ExpressionVariables variables = Utils.getDefaultExpressionVariables(null, null, null, configuration != null ? configuration.asObjectable() : null);
try {
ExpressionEnvironment<?> env = new ExpressionEnvironment<>(coordinatorTask, opResult);
ModelExpressionThreadLocalHolder.pushExpressionEnvironment(env);
query = ExpressionUtil.evaluateQueryExpressions(query, variables, expressionFactory, prismContext, "evaluate query expressions", coordinatorTask, opResult);
} finally {
ModelExpressionThreadLocalHolder.popExpressionEnvironment();
}
}
} catch (SchemaException | ObjectNotFoundException | ExpressionEvaluationException e) {
logErrorAndSetResult(runResult, resultHandler, "Error while evaluating expressions in a search filter", e, OperationResultStatus.FATAL_ERROR, TaskRunResultStatus.PERMANENT_ERROR);
return runResult;
}
Class<? extends ObjectType> type = getType(coordinatorTask);
Collection<SelectorOptions<GetOperationOptions>> queryOptions = createQueryOptions(resultHandler, runResult, coordinatorTask, opResult);
boolean useRepository = useRepositoryDirectly(resultHandler, runResult, coordinatorTask, opResult);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("{}: searching {} with options {}, using query:\n{}", taskName, type, queryOptions, query.debugDump());
}
try {
// counting objects can be within try-catch block, because the handling is similar to handling errors within searchIterative
Long expectedTotal = null;
if (countObjectsOnStart) {
if (!useRepository) {
Integer expectedTotalInt = modelObjectResolver.countObjects(type, query, queryOptions, coordinatorTask, opResult);
if (expectedTotalInt != null) {
// conversion would fail on null
expectedTotal = (long) expectedTotalInt;
}
} else {
expectedTotal = (long) repositoryService.countObjects(type, query, opResult);
}
LOGGER.trace("{}: expecting {} objects to be processed", taskName, expectedTotal);
}
runResult.setProgress(0);
coordinatorTask.setProgress(0);
if (expectedTotal != null) {
coordinatorTask.setExpectedTotal(expectedTotal);
}
try {
coordinatorTask.savePendingModifications(opResult);
} catch (ObjectAlreadyExistsException e) {
// other exceptions are handled in the outer try block
throw new IllegalStateException("Unexpected ObjectAlreadyExistsException when updating task progress/expectedTotal", e);
}
resultHandler.createWorkerThreads(coordinatorTask, opResult);
if (!useRepository) {
modelObjectResolver.searchIterative((Class<O>) type, query, queryOptions, resultHandler, coordinatorTask, opResult);
} else {
// TODO think about this
repositoryService.searchObjectsIterative(type, query, (ResultHandler) resultHandler, null, false, opResult);
}
resultHandler.completeProcessing(coordinatorTask, opResult);
} catch (ObjectNotFoundException e) {
// This is bad. The resource does not exist. Permanent problem.
logErrorAndSetResult(runResult, resultHandler, "Object not found", e, OperationResultStatus.FATAL_ERROR, TaskRunResultStatus.PERMANENT_ERROR);
return runResult;
} catch (CommunicationException e) {
// Error, but not critical. Just try later.
logErrorAndSetResult(runResult, resultHandler, "Communication error", e, OperationResultStatus.PARTIAL_ERROR, TaskRunResultStatus.TEMPORARY_ERROR);
return runResult;
} catch (SchemaException e) {
// Not sure about this. But most likely it is a misconfigured resource or connector
// It may be worth to retry. Error is fatal, but may not be permanent.
logErrorAndSetResult(runResult, resultHandler, "Error dealing with schema", e, OperationResultStatus.FATAL_ERROR, TaskRunResultStatus.TEMPORARY_ERROR);
return runResult;
} catch (RuntimeException e) {
// Can be anything ... but we can't recover from that.
// It is most likely a programming error. Does not make much sense to retry.
logErrorAndSetResult(runResult, resultHandler, "Internal error", e, OperationResultStatus.FATAL_ERROR, TaskRunResultStatus.PERMANENT_ERROR);
return runResult;
} catch (ConfigurationException e) {
// Not sure about this. But most likely it is a misconfigured resource or connector
// It may be worth to retry. Error is fatal, but may not be permanent.
logErrorAndSetResult(runResult, resultHandler, "Configuration error", e, OperationResultStatus.FATAL_ERROR, TaskRunResultStatus.TEMPORARY_ERROR);
return runResult;
} catch (SecurityViolationException e) {
logErrorAndSetResult(runResult, resultHandler, "Security violation", e, OperationResultStatus.FATAL_ERROR, TaskRunResultStatus.PERMANENT_ERROR);
return runResult;
} catch (ExpressionEvaluationException e) {
logErrorAndSetResult(runResult, resultHandler, "Expression error", e, OperationResultStatus.FATAL_ERROR, TaskRunResultStatus.PERMANENT_ERROR);
return runResult;
}
// TODO: check last handler status
handlers.remove(coordinatorTask.getOid());
runResult.setProgress(resultHandler.getProgress());
runResult.setRunResultStatus(TaskRunResultStatus.FINISHED);
if (logFinishInfo) {
String finishMessage = "Finished " + taskName + " (" + coordinatorTask + "). ";
String statistics = "Processed " + resultHandler.getProgress() + " objects in " + resultHandler.getWallTime() / 1000 + " seconds, got " + resultHandler.getErrors() + " errors.";
if (resultHandler.getProgress() > 0) {
statistics += " Average time for one object: " + resultHandler.getAverageTime() + " milliseconds" + " (wall clock time average: " + resultHandler.getWallAverageTime() + " ms).";
}
if (!coordinatorTask.canRun()) {
statistics += " Task was interrupted during processing.";
}
opResult.createSubresult(taskOperationPrefix + ".statistics").recordStatus(OperationResultStatus.SUCCESS, statistics);
TaskHandlerUtil.appendLastFailuresInformation(taskOperationPrefix, coordinatorTask, opResult);
LOGGER.info("{}", finishMessage + statistics);
}
try {
finish(resultHandler, runResult, coordinatorTask, opResult);
} catch (SchemaException e) {
logErrorAndSetResult(runResult, resultHandler, "Schema error while finishing the run", e, OperationResultStatus.FATAL_ERROR, TaskRunResultStatus.PERMANENT_ERROR);
return runResult;
}
LOGGER.trace("{} run finished (task {}, run result {})", taskName, coordinatorTask, runResult);
return runResult;
}
use of com.evolveum.midpoint.xml.ns._public.common.common_3.SystemConfigurationType in project midpoint by Evolveum.
the class SynchronizationServiceImpl method notifyChange.
@Override
public void notifyChange(ResourceObjectShadowChangeDescription change, Task task, OperationResult parentResult) {
validate(change);
Validate.notNull(parentResult, "Parent operation result must not be null.");
boolean logDebug = isLogDebug(change);
if (logDebug) {
LOGGER.debug("SYNCHRONIZATION: received change notification {}", change);
} else {
LOGGER.trace("SYNCHRONIZATION: received change notification {}", change);
}
OperationResult subResult = parentResult.createSubresult(NOTIFY_CHANGE);
PrismObject<? extends ShadowType> currentShadow = change.getCurrentShadow();
PrismObject<? extends ShadowType> applicableShadow = currentShadow;
if (applicableShadow == null) {
// We need this e.g. in case of delete
applicableShadow = change.getOldShadow();
}
SynchronizationEventInformation eventInfo = new SynchronizationEventInformation(applicableShadow, change.getSourceChannel(), task);
try {
ResourceType resourceType = change.getResource().asObjectable();
PrismObject<SystemConfigurationType> configuration = systemObjectCache.getSystemConfiguration(subResult);
ObjectSynchronizationType synchronizationPolicy = determineSynchronizationPolicy(resourceType, applicableShadow, configuration, task, subResult);
if (LOGGER.isTraceEnabled()) {
String policyDesc = null;
if (synchronizationPolicy != null) {
if (synchronizationPolicy.getName() == null) {
policyDesc = "(kind=" + synchronizationPolicy.getKind() + ", intent=" + synchronizationPolicy.getIntent() + ", objectclass=" + synchronizationPolicy.getObjectClass() + ")";
} else {
policyDesc = synchronizationPolicy.getName();
}
}
LOGGER.trace("SYNCHRONIZATION determined policy: {}", policyDesc);
}
if (synchronizationPolicy == null) {
String message = "SYNCHRONIZATION no matching policy for " + applicableShadow + " (" + applicableShadow.asObjectable().getObjectClass() + ") " + " on " + resourceType + ", ignoring change from channel " + change.getSourceChannel();
LOGGER.debug(message);
subResult.recordStatus(OperationResultStatus.NOT_APPLICABLE, message);
eventInfo.setNoSynchronizationPolicy();
eventInfo.record(task);
return;
}
if (!isSynchronizationEnabled(synchronizationPolicy)) {
String message = "SYNCHRONIZATION is not enabled for " + resourceType + " ignoring change from channel " + change.getSourceChannel();
LOGGER.debug(message);
subResult.recordStatus(OperationResultStatus.NOT_APPLICABLE, message);
eventInfo.setSynchronizationNotEnabled();
eventInfo.record(task);
return;
}
// defined in task
if (!satisfyTaskConstraints(synchronizationPolicy, task)) {
LOGGER.trace("SYNCHRONIZATION skipping {} because it does not match kind/intent defined in task", new Object[] { applicableShadow });
subResult.recordStatus(OperationResultStatus.NOT_APPLICABLE, "Skipped because it does not match objectClass/kind/intent");
eventInfo.setDoesNotMatchTaskSpecification();
eventInfo.record(task);
return;
}
if (isProtected((PrismObject<ShadowType>) currentShadow)) {
if (StringUtils.isNotBlank(synchronizationPolicy.getIntent())) {
List<PropertyDelta<?>> modifications = SynchronizationUtils.createSynchronizationTimestampsDelta(currentShadow);
PropertyDelta<String> intentDelta = PropertyDelta.createModificationReplaceProperty(ShadowType.F_INTENT, currentShadow.getDefinition(), synchronizationPolicy.getIntent());
modifications.add(intentDelta);
try {
repositoryService.modifyObject(ShadowType.class, currentShadow.getOid(), modifications, subResult);
task.recordObjectActionExecuted(currentShadow, ChangeType.MODIFY, null);
} catch (Throwable t) {
task.recordObjectActionExecuted(currentShadow, ChangeType.MODIFY, t);
} finally {
task.markObjectActionExecutedBoundary();
}
}
subResult.recordSuccess();
eventInfo.record(task);
LOGGER.debug("SYNCHRONIZATION: DONE (dry run) for protected shadow {}", currentShadow);
return;
}
Class<? extends FocusType> focusType = determineFocusClass(synchronizationPolicy, resourceType);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Synchronization is enabled, focus class: {}, found applicable policy: {}", focusType, Utils.getPolicyDesc(synchronizationPolicy));
}
SynchronizationSituation situation = determineSituation(focusType, change, synchronizationPolicy, configuration.asObjectable(), task, subResult);
if (logDebug) {
LOGGER.debug("SYNCHRONIZATION: SITUATION: '{}', currentOwner={}, correlatedOwner={}", situation.getSituation().value(), situation.getCurrentOwner(), situation.getCorrelatedOwner());
} else {
LOGGER.trace("SYNCHRONIZATION: SITUATION: '{}', currentOwner={}, correlatedOwner={}", situation.getSituation().value(), situation.getCurrentOwner(), situation.getCorrelatedOwner());
}
eventInfo.setOriginalSituation(situation.getSituation());
// overwritten
eventInfo.setNewSituation(situation.getSituation());
if (change.isUnrelatedChange() || Utils.isDryRun(task)) {
PrismObject object = null;
if (change.getCurrentShadow() != null) {
object = change.getCurrentShadow();
} else if (change.getOldShadow() != null) {
object = change.getOldShadow();
}
Collection modifications = SynchronizationUtils.createSynchronizationSituationAndDescriptionDelta(object, situation.getSituation(), task.getChannel(), false);
if (StringUtils.isNotBlank(synchronizationPolicy.getIntent())) {
modifications.add(PropertyDelta.createModificationReplaceProperty(ShadowType.F_INTENT, object.getDefinition(), synchronizationPolicy.getIntent()));
}
try {
repositoryService.modifyObject(ShadowType.class, object.getOid(), modifications, subResult);
task.recordObjectActionExecuted(object, ChangeType.MODIFY, null);
} catch (Throwable t) {
task.recordObjectActionExecuted(object, ChangeType.MODIFY, t);
} finally {
task.markObjectActionExecutedBoundary();
}
subResult.recordSuccess();
eventInfo.record(task);
LOGGER.debug("SYNCHRONIZATION: DONE (dry run/unrelated) for {}", object);
return;
}
// must be here, because when the reaction has no action, the
// situation will be not set.
PrismObject<ShadowType> newCurrentShadow = saveSyncMetadata((PrismObject<ShadowType>) currentShadow, situation, change, synchronizationPolicy, task, parentResult);
if (newCurrentShadow != null) {
change.setCurrentShadow(newCurrentShadow);
}
SynchronizationSituationType newSituation = reactToChange(focusType, change, synchronizationPolicy, situation, resourceType, logDebug, configuration, task, subResult);
eventInfo.setNewSituation(newSituation);
eventInfo.record(task);
subResult.computeStatus();
} catch (SystemException ex) {
// avoid unnecessary re-wrap
eventInfo.setException(ex);
eventInfo.record(task);
subResult.recordFatalError(ex);
throw ex;
} catch (Exception ex) {
eventInfo.setException(ex);
eventInfo.record(task);
subResult.recordFatalError(ex);
throw new SystemException(ex);
} finally {
task.markObjectActionExecutedBoundary();
// if (LOGGER.isTraceEnabled()) {
// LOGGER.trace(subResult.dump());
// }
}
LOGGER.debug("SYNCHRONIZATION: DONE for {}", currentShadow);
}
use of com.evolveum.midpoint.xml.ns._public.common.common_3.SystemConfigurationType in project midpoint by Evolveum.
the class SynchronizationServiceImpl method evaluateSynchronizationPolicyCondition.
private Boolean evaluateSynchronizationPolicyCondition(ObjectSynchronizationType synchronizationPolicy, PrismObject<? extends ShadowType> currentShadow, PrismObject<ResourceType> resource, PrismObject<SystemConfigurationType> configuration, Task task, OperationResult result) throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException {
if (synchronizationPolicy.getCondition() == null) {
return null;
}
ExpressionType conditionExpressionType = synchronizationPolicy.getCondition();
String desc = "condition in object synchronization " + synchronizationPolicy.getName();
ExpressionVariables variables = Utils.getDefaultExpressionVariables(null, currentShadow, null, resource, configuration, null);
try {
ModelExpressionThreadLocalHolder.pushExpressionEnvironment(new ExpressionEnvironment<>(task, result));
PrismPropertyValue<Boolean> evaluateCondition = ExpressionUtil.evaluateCondition(variables, conditionExpressionType, expressionFactory, desc, task, result);
return evaluateCondition.getValue();
} finally {
ModelExpressionThreadLocalHolder.popExpressionEnvironment();
}
}
Aggregations