use of com.evolveum.midpoint.repo.api.RepoAddOptions in project midpoint by Evolveum.
the class ChangeExecutor method executeAddition.
private <T extends ObjectType, F extends ObjectType> void executeAddition(ObjectDelta<T> change, final LensContext<F> context, LensElementContext<T> objectContext, ModelExecuteOptions options, ResourceType resource, Task task, OperationResult result) throws ObjectAlreadyExistsException, ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException {
PrismObject<T> objectToAdd = change.getObjectToAdd();
if (change.getModifications() != null) {
for (ItemDelta delta : change.getModifications()) {
delta.applyTo(objectToAdd);
}
change.getModifications().clear();
}
OwnerResolver ownerResolver = createOwnerResolver(context, task, result);
try {
securityEnforcer.authorize(ModelAuthorizationAction.ADD.getUrl(), AuthorizationPhaseType.EXECUTION, objectToAdd, null, null, ownerResolver, result);
T objectTypeToAdd = objectToAdd.asObjectable();
metadataManager.applyMetadataAdd(context, objectToAdd, clock.currentTimeXMLGregorianCalendar(), task, result);
if (options == null && context != null) {
options = context.getOptions();
}
String oid;
if (objectTypeToAdd instanceof TaskType) {
oid = addTask((TaskType) objectTypeToAdd, result);
} else if (objectTypeToAdd instanceof NodeType) {
throw new UnsupportedOperationException("NodeType cannot be added using model interface");
} else if (ObjectTypes.isManagedByProvisioning(objectTypeToAdd)) {
ProvisioningOperationOptions provisioningOptions = getProvisioningOptions(context, options);
oid = addProvisioningObject(objectToAdd, context, objectContext, provisioningOptions, resource, task, result);
if (oid == null) {
throw new SystemException("Provisioning addObject returned null OID while adding " + objectToAdd);
}
result.addReturn("createdAccountOid", oid);
} else {
FocusConstraintsChecker.clearCacheFor(objectToAdd.asObjectable().getName());
RepoAddOptions addOpt = new RepoAddOptions();
if (ModelExecuteOptions.isOverwrite(options)) {
addOpt.setOverwrite(true);
}
if (ModelExecuteOptions.isNoCrypt(options)) {
addOpt.setAllowUnencryptedValues(true);
}
oid = cacheRepositoryService.addObject(objectToAdd, addOpt, result);
if (oid == null) {
throw new SystemException("Repository addObject returned null OID while adding " + objectToAdd);
}
}
change.setOid(oid);
task.recordObjectActionExecuted(objectToAdd, objectToAdd.getCompileTimeClass(), oid, ChangeType.ADD, context.getChannel(), null);
} catch (Throwable t) {
task.recordObjectActionExecuted(objectToAdd, objectToAdd.getCompileTimeClass(), null, ChangeType.ADD, context.getChannel(), t);
throw t;
}
}
use of com.evolveum.midpoint.repo.api.RepoAddOptions in project midpoint by Evolveum.
the class AbstractIntegrationTest method addResourceFromFile.
protected PrismObject<ResourceType> addResourceFromFile(File file, String connectorType, boolean overwrite, OperationResult result) throws JAXBException, SchemaException, ObjectAlreadyExistsException, EncryptionException, IOException {
LOGGER.trace("addObjectFromFile: {}, connector type {}", file, connectorType);
PrismObject<ResourceType> resource = prismContext.parseObject(file);
fillInConnectorRef(resource, connectorType, result);
CryptoUtil.encryptValues(protector, resource);
display("Adding resource ", resource);
RepoAddOptions options = null;
if (overwrite) {
options = RepoAddOptions.createOverwrite();
}
String oid = repositoryService.addObject(resource, options, result);
resource.setOid(oid);
return resource;
}
use of com.evolveum.midpoint.repo.api.RepoAddOptions in project midpoint by Evolveum.
the class SqlRepositoryServiceImpl method addObject.
@Override
public <T extends ObjectType> String addObject(PrismObject<T> object, RepoAddOptions options, OperationResult result) throws ObjectAlreadyExistsException, SchemaException {
Validate.notNull(object, "Object must not be null.");
validateName(object);
Validate.notNull(result, "Operation result must not be null.");
if (options == null) {
options = new RepoAddOptions();
}
LOGGER.debug("Adding object type '{}', overwrite={}, allowUnencryptedValues={}", object.getCompileTimeClass().getSimpleName(), options.isOverwrite(), options.isAllowUnencryptedValues());
if (InternalsConfig.encryptionChecks && !RepoAddOptions.isAllowUnencryptedValues(options)) {
CryptoUtil.checkEncrypted(object);
}
if (InternalsConfig.consistencyChecks) {
object.checkConsistence(ConsistencyCheckScope.THOROUGH);
} else {
object.checkConsistence(ConsistencyCheckScope.MANDATORY_CHECKS_ONLY);
}
if (LOGGER.isTraceEnabled()) {
// Explicitly log name
PolyStringType namePolyType = object.asObjectable().getName();
LOGGER.trace("NAME: {} - {}", namePolyType.getOrig(), namePolyType.getNorm());
}
OperationResult subResult = result.createSubresult(ADD_OBJECT);
subResult.addParam("object", object);
subResult.addParam("options", options);
final String operation = "adding";
int attempt = 1;
String oid = object.getOid();
while (true) {
try {
return objectUpdater.addObjectAttempt(object, options, subResult);
} catch (RuntimeException ex) {
attempt = baseHelper.logOperationAttempt(oid, operation, attempt, ex, subResult);
}
}
}
use of com.evolveum.midpoint.repo.api.RepoAddOptions in project midpoint by Evolveum.
the class ModelController method executeChanges.
/* (non-Javadoc)
* @see com.evolveum.midpoint.model.api.ModelService#executeChanges(java.util.Collection, com.evolveum.midpoint.task.api.Task, com.evolveum.midpoint.schema.result.OperationResult)
*/
@Override
public Collection<ObjectDeltaOperation<? extends ObjectType>> executeChanges(final Collection<ObjectDelta<? extends ObjectType>> deltas, ModelExecuteOptions options, Task task, Collection<ProgressListener> statusListeners, OperationResult parentResult) throws ObjectAlreadyExistsException, ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, PolicyViolationException, SecurityViolationException {
Collection<ObjectDeltaOperation<? extends ObjectType>> executedDeltas = new ArrayList<>();
OperationResult result = parentResult.createSubresult(EXECUTE_CHANGES);
result.addParam(OperationResult.PARAM_OPTIONS, options);
// 3) for MODIFY operation: filters contained in deltas -> these have to be treated here, because if OID is missing from such a delta, the change would be rejected by the repository
if (ModelExecuteOptions.isReevaluateSearchFilters(options)) {
for (ObjectDelta<? extends ObjectType> delta : deltas) {
Utils.resolveReferences(delta, cacheRepositoryService, false, true, EvaluationTimeType.IMPORT, true, prismContext, result);
}
} else if (ModelExecuteOptions.isIsImport(options)) {
// if plain import is requested, we simply evaluate filters in ADD operation (and we do not force reevaluation if OID is already set)
for (ObjectDelta<? extends ObjectType> delta : deltas) {
if (delta.isAdd()) {
Utils.resolveReferences(delta.getObjectToAdd(), cacheRepositoryService, false, false, EvaluationTimeType.IMPORT, true, prismContext, result);
}
}
}
// Make sure everything is encrypted as needed before logging anything.
// But before that we need to make sure that we have proper definition, otherwise we
// might miss some encryptable data in dynamic schemas
applyDefinitions(deltas, options, task, result);
Utils.encrypt(deltas, protector, options, result);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("MODEL.executeChanges(\n deltas:\n{}\n options:{}", DebugUtil.debugDump(deltas, 2), options);
}
if (InternalsConfig.consistencyChecks) {
OperationResultRunner.run(result, () -> {
for (ObjectDelta<? extends ObjectType> delta : deltas) {
delta.checkConsistence();
}
});
}
RepositoryCache.enter();
try {
if (ModelExecuteOptions.isRaw(options)) {
// Go directly to repository
AuditEventRecord auditRecord = new AuditEventRecord(AuditEventType.EXECUTE_CHANGES_RAW, AuditEventStage.REQUEST);
auditRecord.addDeltas(ObjectDeltaOperation.cloneDeltaCollection(deltas));
auditRecord.setTarget(Utils.determineAuditTarget(deltas));
// we don't know auxiliary information (resource, objectName) at this moment -- so we do nothing
auditService.audit(auditRecord, task);
try {
for (ObjectDelta<? extends ObjectType> delta : deltas) {
OperationResult result1 = result.createSubresult(EXECUTE_CHANGE);
// MID-2486
if (delta.getObjectTypeClass() == ShadowType.class || delta.getObjectTypeClass() == ResourceType.class) {
try {
provisioning.applyDefinition(delta, task, result1);
} catch (SchemaException | ObjectNotFoundException | CommunicationException | ConfigurationException | RuntimeException e) {
// we can tolerate this - if there's a real problem with definition, repo call below will fail
LoggingUtils.logExceptionAsWarning(LOGGER, "Couldn't apply definition on shadow/resource raw-mode delta {} -- continuing the operation.", e, delta);
result1.muteLastSubresultError();
}
}
final boolean preAuthorized = ModelExecuteOptions.isPreAuthorized(options);
PrismObject objectToDetermineDetailsForAudit = null;
try {
if (delta.isAdd()) {
RepoAddOptions repoOptions = new RepoAddOptions();
if (ModelExecuteOptions.isNoCrypt(options)) {
repoOptions.setAllowUnencryptedValues(true);
}
if (ModelExecuteOptions.isOverwrite(options)) {
repoOptions.setOverwrite(true);
}
PrismObject<? extends ObjectType> objectToAdd = delta.getObjectToAdd();
if (!preAuthorized) {
securityEnforcer.authorize(ModelAuthorizationAction.ADD.getUrl(), null, objectToAdd, null, null, null, result1);
}
String oid;
try {
oid = cacheRepositoryService.addObject(objectToAdd, repoOptions, result1);
task.recordObjectActionExecuted(objectToAdd, null, oid, ChangeType.ADD, task.getChannel(), null);
} catch (Throwable t) {
task.recordObjectActionExecuted(objectToAdd, null, null, ChangeType.ADD, task.getChannel(), t);
throw t;
}
delta.setOid(oid);
objectToDetermineDetailsForAudit = objectToAdd;
} else if (delta.isDelete()) {
// MID-2218
QNameUtil.setTemporarilyTolerateUndeclaredPrefixes(true);
try {
PrismObject<? extends ObjectType> existingObject = null;
try {
existingObject = cacheRepositoryService.getObject(delta.getObjectTypeClass(), delta.getOid(), null, result1);
objectToDetermineDetailsForAudit = existingObject;
} catch (Throwable t) {
if (!securityEnforcer.isAuthorized(AuthorizationConstants.AUTZ_ALL_URL, null, null, null, null, null)) {
throw t;
} else {
// in case of administrator's request we continue - in order to allow deleting malformed (unreadable) objects
}
}
if (!preAuthorized) {
securityEnforcer.authorize(ModelAuthorizationAction.DELETE.getUrl(), null, existingObject, null, null, null, result1);
}
try {
if (ObjectTypes.isClassManagedByProvisioning(delta.getObjectTypeClass())) {
Utils.clearRequestee(task);
provisioning.deleteObject(delta.getObjectTypeClass(), delta.getOid(), ProvisioningOperationOptions.createRaw(), null, task, result1);
} else {
cacheRepositoryService.deleteObject(delta.getObjectTypeClass(), delta.getOid(), result1);
}
task.recordObjectActionExecuted(objectToDetermineDetailsForAudit, delta.getObjectTypeClass(), delta.getOid(), ChangeType.DELETE, task.getChannel(), null);
} catch (Throwable t) {
task.recordObjectActionExecuted(objectToDetermineDetailsForAudit, delta.getObjectTypeClass(), delta.getOid(), ChangeType.DELETE, task.getChannel(), t);
throw t;
}
} finally {
QNameUtil.setTemporarilyTolerateUndeclaredPrefixes(false);
}
} else if (delta.isModify()) {
// MID-2218
QNameUtil.setTemporarilyTolerateUndeclaredPrefixes(true);
try {
PrismObject existingObject = cacheRepositoryService.getObject(delta.getObjectTypeClass(), delta.getOid(), null, result1);
objectToDetermineDetailsForAudit = existingObject;
if (!preAuthorized) {
securityEnforcer.authorize(ModelAuthorizationAction.MODIFY.getUrl(), null, existingObject, delta, null, null, result1);
}
try {
cacheRepositoryService.modifyObject(delta.getObjectTypeClass(), delta.getOid(), delta.getModifications(), result1);
task.recordObjectActionExecuted(existingObject, ChangeType.MODIFY, null);
} catch (Throwable t) {
task.recordObjectActionExecuted(existingObject, ChangeType.MODIFY, t);
throw t;
}
} finally {
QNameUtil.setTemporarilyTolerateUndeclaredPrefixes(false);
}
if (ModelExecuteOptions.isReevaluateSearchFilters(options)) {
// treat filters that already exist in the object (case #2 above)
reevaluateSearchFilters(delta.getObjectTypeClass(), delta.getOid(), task, result1);
}
} else {
throw new IllegalArgumentException("Wrong delta type " + delta.getChangeType() + " in " + delta);
}
} catch (ObjectAlreadyExistsException | SchemaException | ObjectNotFoundException | ConfigurationException | CommunicationException | SecurityViolationException | RuntimeException e) {
ModelUtils.recordFatalError(result1, e);
throw e;
} finally {
// to have a record with the failed delta as well
result1.computeStatus();
ObjectDeltaOperation<? extends ObjectType> odoToAudit = new ObjectDeltaOperation<>(delta, result1);
if (objectToDetermineDetailsForAudit != null) {
odoToAudit.setObjectName(objectToDetermineDetailsForAudit.getName());
if (objectToDetermineDetailsForAudit.asObjectable() instanceof ShadowType) {
ShadowType shadow = (ShadowType) objectToDetermineDetailsForAudit.asObjectable();
odoToAudit.setResourceOid(ShadowUtil.getResourceOid(shadow));
odoToAudit.setResourceName(ShadowUtil.getResourceName(shadow));
}
}
executedDeltas.add(odoToAudit);
}
}
} finally {
cleanupOperationResult(result);
auditRecord.setTimestamp(System.currentTimeMillis());
auditRecord.setOutcome(result.getStatus());
auditRecord.setEventStage(AuditEventStage.EXECUTION);
auditRecord.getDeltas().clear();
auditRecord.getDeltas().addAll(executedDeltas);
auditService.audit(auditRecord, task);
task.markObjectActionExecutedBoundary();
}
} else {
try {
LensContext<? extends ObjectType> context = contextFactory.createContext(deltas, options, task, result);
if (ModelExecuteOptions.isReevaluateSearchFilters(options)) {
String m = "ReevaluateSearchFilters option is not fully supported for non-raw operations yet. Filters already present in the object will not be touched.";
LOGGER.warn("{} Context = {}", m, context.debugDump());
result.createSubresult(CLASS_NAME_WITH_DOT + "reevaluateSearchFilters").recordWarning(m);
}
context.setProgressListeners(statusListeners);
// Note: Request authorization happens inside clockwork
clockwork.run(context, task, result);
// prepare return value
if (context.getFocusContext() != null) {
executedDeltas.addAll(context.getFocusContext().getExecutedDeltas());
}
for (LensProjectionContext projectionContext : context.getProjectionContexts()) {
executedDeltas.addAll(projectionContext.getExecutedDeltas());
}
if (context.hasExplosiveProjection()) {
PrismObject<? extends ObjectType> focus = context.getFocusContext().getObjectAny();
LOGGER.debug("Recomputing {} because there was explosive projection", focus);
LensContext<? extends ObjectType> recomputeContext = contextFactory.createRecomputeContext(focus, options, task, result);
recomputeContext.setDoReconciliationForAllProjections(true);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Recomputing {}, context:\n{}", focus, recomputeContext.debugDump());
}
clockwork.run(recomputeContext, task, result);
}
cleanupOperationResult(result);
} catch (ObjectAlreadyExistsException | ObjectNotFoundException | SchemaException | ExpressionEvaluationException | CommunicationException | ConfigurationException | PolicyViolationException | SecurityViolationException | RuntimeException e) {
ModelUtils.recordFatalError(result, e);
throw e;
} finally {
task.markObjectActionExecutedBoundary();
}
}
invalidateCaches(executedDeltas);
} catch (RuntimeException e) {
// just for sure (TODO split this method into two: raw and non-raw case)
ModelUtils.recordFatalError(result, e);
throw e;
} finally {
RepositoryCache.exit();
}
return executedDeltas;
}
use of com.evolveum.midpoint.repo.api.RepoAddOptions in project midpoint by Evolveum.
the class ProvisioningServiceImpl method addObject.
@Override
public <T extends ObjectType> String addObject(PrismObject<T> object, OperationProvisioningScriptsType scripts, ProvisioningOperationOptions options, Task task, OperationResult parentResult) throws ObjectAlreadyExistsException, SchemaException, CommunicationException, ObjectNotFoundException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException {
Validate.notNull(object, "Object to add must not be null.");
Validate.notNull(parentResult, "Operation result must not be null.");
if (InternalsConfig.encryptionChecks) {
CryptoUtil.checkEncrypted(object);
}
OperationResult result = parentResult.createSubresult(ProvisioningService.class.getName() + ".addObject");
result.addParam("object", object);
result.addParam("scripts", scripts);
result.addContext(OperationResult.CONTEXT_IMPLEMENTATION_CLASS, ProvisioningServiceImpl.class);
String oid = null;
if (object.canRepresent(ShadowType.class)) {
try {
// calling shadow cache to add object
oid = getShadowCache(Mode.STANDARD).addShadow((PrismObject<ShadowType>) object, scripts, null, options, task, result);
LOGGER.trace("**PROVISIONING: Added shadow object {}", oid);
result.computeStatus();
} catch (GenericFrameworkException ex) {
ProvisioningUtil.recordFatalError(LOGGER, result, "Couldn't add object " + object + ". Reason: " + ex.getMessage(), ex);
throw new CommunicationException(ex.getMessage(), ex);
} catch (SchemaException ex) {
ProvisioningUtil.recordFatalError(LOGGER, result, "Couldn't add object. Schema violation: " + ex.getMessage(), ex);
throw new SchemaException("Couldn't add object. Schema violation: " + ex.getMessage(), ex);
} catch (ObjectAlreadyExistsException ex) {
result.computeStatus();
if (!result.isSuccess() && !result.isHandledError()) {
ProvisioningUtil.recordFatalError(LOGGER, result, "Couldn't add object. Object already exist: " + ex.getMessage(), ex);
} else {
result.recordSuccess();
}
result.cleanupResult(ex);
throw new ObjectAlreadyExistsException("Couldn't add object. Object already exists: " + ex.getMessage(), ex);
} catch (ConfigurationException ex) {
ProvisioningUtil.recordFatalError(LOGGER, result, "Couldn't add object. Configuration error: " + ex.getMessage(), ex);
throw ex;
} catch (SecurityViolationException ex) {
ProvisioningUtil.recordFatalError(LOGGER, result, "Couldn't add object. Security violation: " + ex.getMessage(), ex);
throw ex;
} catch (ExpressionEvaluationException ex) {
ProvisioningUtil.recordFatalError(LOGGER, result, "Couldn't add object. Expression error: " + ex.getMessage(), ex);
throw ex;
} catch (RuntimeException | Error ex) {
ProvisioningUtil.recordFatalError(LOGGER, result, "Couldn't add object. Runtime error: " + ex.getMessage(), ex);
throw ex;
}
} else {
RepoAddOptions addOptions = null;
if (ProvisioningOperationOptions.isOverwrite(options)) {
addOptions = RepoAddOptions.createOverwrite();
}
oid = cacheRepositoryService.addObject(object, addOptions, result);
result.computeStatus();
}
result.cleanupResult();
return oid;
}
Aggregations