use of com.evolveum.midpoint.provisioning.ucf.api.GenericFrameworkException in project midpoint by Evolveum.
the class ResourceObjectReferenceResolver method fetchResourceObject.
public PrismObject<ShadowType> fetchResourceObject(ProvisioningContext ctx, Collection<? extends ResourceAttribute<?>> identifiers, AttributesToReturn attributesToReturn, OperationResult parentResult) throws ObjectNotFoundException, CommunicationException, SchemaException, SecurityViolationException, ConfigurationException, ExpressionEvaluationException {
ResourceType resource = ctx.getResource();
ConnectorInstance connector = ctx.getConnector(ReadCapabilityType.class, parentResult);
RefinedObjectClassDefinition objectClassDefinition = ctx.getObjectClassDefinition();
try {
if (!ResourceTypeUtil.isReadCapabilityEnabled(resource)) {
throw new UnsupportedOperationException("Resource does not support 'read' operation");
}
ResourceObjectIdentification identification = ResourceObjectIdentification.create(objectClassDefinition, identifiers);
identification = resolvePrimaryIdentifiers(ctx, identification, parentResult);
identification.validatePrimaryIdenfiers();
return connector.fetchObject(ShadowType.class, identification, attributesToReturn, ctx, parentResult);
} catch (ObjectNotFoundException e) {
parentResult.recordFatalError("Object not found. Identifiers: " + identifiers + ". Reason: " + e.getMessage(), e);
throw new ObjectNotFoundException("Object not found. identifiers=" + identifiers + ", objectclass=" + PrettyPrinter.prettyPrint(objectClassDefinition.getTypeName()) + ": " + e.getMessage(), e);
} catch (CommunicationException e) {
parentResult.recordFatalError("Error communication with the connector " + connector + ": " + e.getMessage(), e);
throw e;
} catch (GenericFrameworkException e) {
parentResult.recordFatalError("Generic error in the connector " + connector + ". Reason: " + e.getMessage(), e);
throw new GenericConnectorException("Generic error in the connector " + connector + ". Reason: " + e.getMessage(), e);
} catch (SchemaException ex) {
parentResult.recordFatalError("Can't get resource object, schema error: " + ex.getMessage(), ex);
throw ex;
} catch (ExpressionEvaluationException ex) {
parentResult.recordFatalError("Can't get resource object, expression error: " + ex.getMessage(), ex);
throw ex;
} catch (ConfigurationException e) {
parentResult.recordFatalError(e);
throw e;
}
}
use of com.evolveum.midpoint.provisioning.ucf.api.GenericFrameworkException in project midpoint by Evolveum.
the class ShadowCache method countObjects.
public Integer countObjects(ObjectQuery query, Task task, final OperationResult result) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException {
ResourceShadowDiscriminator coordinates = ObjectQueryUtil.getCoordinates(query.getFilter());
final ProvisioningContext ctx = ctxFactory.create(coordinates, null, result);
ctx.assertDefinition();
applyDefinition(ctx, query);
RefinedObjectClassDefinition objectClassDef = ctx.getObjectClassDefinition();
ResourceType resourceType = ctx.getResource();
CountObjectsCapabilityType countObjectsCapabilityType = objectClassDef.getEffectiveCapability(CountObjectsCapabilityType.class);
if (countObjectsCapabilityType == null) {
// Unable to count. Return null which means "I do not know"
result.recordNotApplicableIfUnknown();
return null;
} else {
CountObjectsSimulateType simulate = countObjectsCapabilityType.getSimulate();
if (simulate == null) {
// We have native capability
ConnectorInstance connector = ctx.getConnector(ReadCapabilityType.class, result);
try {
ObjectQuery attributeQuery = createAttributeQuery(query);
int count;
try {
count = connector.count(objectClassDef.getObjectClassDefinition(), attributeQuery, objectClassDef.getPagedSearches(), ctx, result);
} catch (CommunicationException | GenericFrameworkException | SchemaException | UnsupportedOperationException e) {
result.recordFatalError(e);
throw e;
}
result.computeStatus();
result.cleanupResult();
return count;
} catch (GenericFrameworkException | UnsupportedOperationException e) {
SystemException ex = new SystemException("Couldn't count objects on resource " + resourceType + ": " + e.getMessage(), e);
result.recordFatalError(ex);
throw ex;
}
} else if (simulate == CountObjectsSimulateType.PAGED_SEARCH_ESTIMATE) {
if (!objectClassDef.isPagedSearchEnabled()) {
throw new ConfigurationException("Configured count object capability to be simulated using a paged search but paged search capability is not present");
}
final Holder<Integer> countHolder = new Holder<Integer>(0);
final ShadowHandler<ShadowType> handler = new ShadowHandler<ShadowType>() {
@Override
public boolean handle(ShadowType object) {
int count = countHolder.getValue();
count++;
countHolder.setValue(count);
return true;
}
};
query = query.clone();
ObjectPaging paging = ObjectPaging.createEmptyPaging();
paging.setMaxSize(1);
query.setPaging(paging);
Collection<SelectorOptions<GetOperationOptions>> options = SelectorOptions.createCollection(new ItemPath(ShadowType.F_ASSOCIATION), GetOperationOptions.createRetrieve(RetrieveOption.EXCLUDE));
SearchResultMetadata resultMetadata;
try {
resultMetadata = searchObjectsIterative(query, options, handler, false, task, result);
} catch (SchemaException | ObjectNotFoundException | ConfigurationException | SecurityViolationException e) {
result.recordFatalError(e);
throw e;
}
result.computeStatus();
result.cleanupResult();
return resultMetadata.getApproxNumberOfAllResults();
} else if (simulate == CountObjectsSimulateType.SEQUENTIAL_SEARCH) {
// traditional way of counting objects (i.e. counting them one
// by one)
final Holder<Integer> countHolder = new Holder<Integer>(0);
final ShadowHandler<ShadowType> handler = new ShadowHandler<ShadowType>() {
@Override
public boolean handle(ShadowType object) {
int count = countHolder.getValue();
count++;
countHolder.setValue(count);
return true;
}
};
Collection<SelectorOptions<GetOperationOptions>> options = SelectorOptions.createCollection(new ItemPath(ShadowType.F_ASSOCIATION), GetOperationOptions.createRetrieve(RetrieveOption.EXCLUDE));
searchObjectsIterative(query, options, handler, false, task, result);
// TODO: better error handling
result.computeStatus();
result.cleanupResult();
return countHolder.getValue();
} else {
throw new IllegalArgumentException("Unknown count capability simulate type " + simulate);
}
}
}
use of com.evolveum.midpoint.provisioning.ucf.api.GenericFrameworkException in project midpoint by Evolveum.
the class ShadowCache method modifyShadow.
public String modifyShadow(PrismObject<ShadowType> repoShadow, String oid, Collection<? extends ItemDelta> modifications, OperationProvisioningScriptsType scripts, ProvisioningOperationOptions options, Task task, OperationResult parentResult) throws CommunicationException, GenericFrameworkException, ObjectNotFoundException, SchemaException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException {
Validate.notNull(repoShadow, "Object to modify must not be null.");
Validate.notNull(oid, "OID must not be null.");
Validate.notNull(modifications, "Object modification must not be null.");
InternalMonitor.recordShadowChangeOperation();
Collection<QName> additionalAuxiliaryObjectClassQNames = new ArrayList<>();
ItemPath auxPath = new ItemPath(ShadowType.F_AUXILIARY_OBJECT_CLASS);
for (ItemDelta modification : modifications) {
if (auxPath.equals(modification.getPath())) {
PropertyDelta<QName> auxDelta = (PropertyDelta<QName>) modification;
for (PrismPropertyValue<QName> pval : auxDelta.getValues(QName.class)) {
additionalAuxiliaryObjectClassQNames.add(pval.getValue());
}
}
}
ProvisioningContext ctx = ctxFactory.create(repoShadow, additionalAuxiliaryObjectClassQNames, task, parentResult);
AsynchronousOperationReturnValue<Collection<PropertyDelta<PrismPropertyValue>>> asyncReturnValue;
try {
ctx.assertDefinition();
RefinedObjectClassDefinition rOCDef = ctx.getObjectClassDefinition();
applyAttributesDefinition(ctx, repoShadow);
accessChecker.checkModify(ctx.getResource(), repoShadow, modifications, ctx.getObjectClassDefinition(), parentResult);
modifications = beforeModifyOnResource(repoShadow, options, modifications);
preprocessEntitlements(ctx, modifications, "delta for shadow " + oid, parentResult);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Applying change: {}", DebugUtil.debugDump(modifications));
}
asyncReturnValue = resouceObjectConverter.modifyResourceObject(ctx, repoShadow, scripts, modifications, parentResult);
} catch (Exception ex) {
LOGGER.debug("Provisioning exception: {}:{}, attempting to handle it", new Object[] { ex.getClass(), ex.getMessage(), ex });
try {
repoShadow = handleError(ctx, ex, repoShadow, FailedOperation.MODIFY, modifications, isDoDiscovery(ctx.getResource(), options), isCompensate(options), parentResult);
parentResult.computeStatus();
} catch (ObjectAlreadyExistsException e) {
parentResult.recordFatalError("While compensating communication problem for modify operation got: " + ex.getMessage(), ex);
throw new SystemException(e);
}
return repoShadow.getOid();
}
Collection<PropertyDelta<PrismPropertyValue>> sideEffectChanges = asyncReturnValue.getReturnValue();
if (sideEffectChanges != null) {
ItemDelta.addAll(modifications, sideEffectChanges);
}
afterModifyOnResource(ctx, repoShadow, modifications, asyncReturnValue.getOperationResult(), parentResult);
ObjectDelta<ShadowType> delta = ObjectDelta.createModifyDelta(repoShadow.getOid(), modifications, repoShadow.getCompileTimeClass(), prismContext);
ResourceOperationDescription operationDescription = createSuccessOperationDescription(ctx, repoShadow, delta, parentResult);
if (asyncReturnValue.isInProgress()) {
operationListener.notifyInProgress(operationDescription, task, parentResult);
parentResult.recordInProgress();
parentResult.setAsynchronousOperationReference(asyncReturnValue.getOperationResult().getAsynchronousOperationReference());
} else {
operationListener.notifySuccess(operationDescription, task, parentResult);
parentResult.recordSuccess();
}
return oid;
}
use of com.evolveum.midpoint.provisioning.ucf.api.GenericFrameworkException in project midpoint by Evolveum.
the class ShadowCache method synchronize.
///////////////////////////////////////////////////////////////////////////
// TODO: maybe split this to a separate class
///////////////////////////////////////////////////////////////////////////
public int synchronize(ResourceShadowDiscriminator shadowCoordinates, PrismProperty<?> lastToken, Task task, OperationResult parentResult) throws ObjectNotFoundException, CommunicationException, GenericFrameworkException, SchemaException, ConfigurationException, SecurityViolationException, ObjectAlreadyExistsException, ExpressionEvaluationException {
InternalMonitor.recordShadowOtherOperation();
final ProvisioningContext ctx = ctxFactory.create(shadowCoordinates, task, parentResult);
List<Change> changes = null;
try {
changes = resouceObjectConverter.fetchChanges(ctx, lastToken, parentResult);
LOGGER.trace("Found {} change(s). Start processing it (them).", changes.size());
int processedChanges = 0;
for (Change change : changes) {
if (change.isTokenOnly()) {
LOGGER.trace("Found token-only change: {}", change);
task.setExtensionProperty(change.getToken());
continue;
}
ObjectClassComplexTypeDefinition changeObjectClassDefinition = change.getObjectClassDefinition();
ProvisioningContext shadowCtx;
PrismObject<ShadowType> oldShadow = null;
if (changeObjectClassDefinition == null) {
if (change.getObjectDelta() != null && change.getObjectDelta().isDelete()) {
oldShadow = change.getOldShadow();
if (oldShadow == null) {
oldShadow = shadowManager.findOrAddShadowFromChangeGlobalContext(ctx, change, parentResult);
}
if (oldShadow == null) {
LOGGER.debug("No old shadow for delete synchronization event {}, we probably did not know about that object anyway, so well be ignoring this event", change);
continue;
}
shadowCtx = ctx.spawn(oldShadow);
} else {
throw new SchemaException("No object class definition in change " + change);
}
} else {
shadowCtx = ctx.spawn(changeObjectClassDefinition.getTypeName());
}
processChange(shadowCtx, change, oldShadow, parentResult);
// such a change should be skipped to process consistent changes
if (change.getOldShadow() == null) {
PrismProperty<?> newToken = change.getToken();
task.setExtensionProperty(newToken);
processedChanges++;
// because
task.setProgress(task.getProgress() + 1);
// processedChanges
// are reflected
// into task
// only at task
// run finish
LOGGER.debug("Skipping processing change. Can't find appropriate shadow (e.g. the object was deleted on the resource meantime).");
continue;
}
boolean isSuccess = processSynchronization(shadowCtx, change, parentResult);
boolean retryUnhandledError = true;
if (task.getExtension() != null) {
PrismProperty tokenRetryUnhandledErrProperty = task.getExtensionProperty(SchemaConstants.SYNC_TOKEN_RETRY_UNHANDLED);
if (tokenRetryUnhandledErrProperty != null) {
retryUnhandledError = (boolean) tokenRetryUnhandledErrProperty.getRealValue();
}
}
if (!retryUnhandledError || isSuccess) {
// // get updated token from change,
// // create property modification from new token
// // and replace old token with the new one
PrismProperty<?> newToken = change.getToken();
task.setExtensionProperty(newToken);
processedChanges++;
// because
task.setProgress(task.getProgress() + 1);
// processedChanges
// are reflected
// into task
// only at task
// run finish
}
}
// also if no changes was detected, update token
if (changes.isEmpty() && lastToken != null) {
LOGGER.trace("No changes to synchronize on " + ctx.getResource());
task.setExtensionProperty(lastToken);
}
task.savePendingModifications(parentResult);
return processedChanges;
} catch (SchemaException | CommunicationException | GenericFrameworkException | ConfigurationException | ObjectNotFoundException | ObjectAlreadyExistsException | ExpressionEvaluationException | RuntimeException | Error ex) {
parentResult.recordFatalError(ex);
throw ex;
}
}
use of com.evolveum.midpoint.provisioning.ucf.api.GenericFrameworkException in project midpoint by Evolveum.
the class ConnectorInstanceConnIdImpl method addObject.
@Override
public AsynchronousOperationReturnValue<Collection<ResourceAttribute<?>>> addObject(PrismObject<? extends ShadowType> shadow, Collection<Operation> additionalOperations, StateReporter reporter, OperationResult parentResult) throws CommunicationException, GenericFrameworkException, SchemaException, ObjectAlreadyExistsException, ConfigurationException {
validateShadow(shadow, "add", false);
ShadowType shadowType = shadow.asObjectable();
ResourceAttributeContainer attributesContainer = ShadowUtil.getAttributesContainer(shadow);
OperationResult result = parentResult.createSubresult(ConnectorInstance.class.getName() + ".addObject");
result.addParam("resourceObject", shadow);
// because of serialization issues
result.addParam("additionalOperations", DebugUtil.debugDump(additionalOperations));
ObjectClassComplexTypeDefinition ocDef;
ResourceAttributeContainerDefinition attrContDef = attributesContainer.getDefinition();
if (attrContDef != null) {
ocDef = attrContDef.getComplexTypeDefinition();
} else {
ocDef = resourceSchema.findObjectClassDefinition(shadow.asObjectable().getObjectClass());
if (ocDef == null) {
throw new SchemaException("Unknown object class " + shadow.asObjectable().getObjectClass());
}
}
// getting icf object class from resource object class
ObjectClass icfObjectClass = connIdNameMapper.objectClassToIcf(shadow, getSchemaNamespace(), connectorType, legacySchema);
if (icfObjectClass == null) {
result.recordFatalError("Couldn't get icf object class from " + shadow);
throw new IllegalArgumentException("Couldn't get icf object class from " + shadow);
}
// setting ifc attributes from resource object attributes
Set<Attribute> attributes = null;
try {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("midPoint object before conversion:\n{}", attributesContainer.debugDump());
}
attributes = connIdConvertor.convertFromResourceObject(attributesContainer, ocDef);
if (shadowType.getCredentials() != null && shadowType.getCredentials().getPassword() != null) {
PasswordType password = shadowType.getCredentials().getPassword();
ProtectedStringType protectedString = password.getValue();
GuardedString guardedPassword = ConnIdUtil.toGuardedString(protectedString, "new password", protector);
if (guardedPassword != null) {
attributes.add(AttributeBuilder.build(OperationalAttributes.PASSWORD_NAME, guardedPassword));
}
}
if (ActivationUtil.hasAdministrativeActivation(shadowType)) {
attributes.add(AttributeBuilder.build(OperationalAttributes.ENABLE_NAME, ActivationUtil.isAdministrativeEnabled(shadowType)));
}
if (ActivationUtil.hasValidFrom(shadowType)) {
attributes.add(AttributeBuilder.build(OperationalAttributes.ENABLE_DATE_NAME, XmlTypeConverter.toMillis(shadowType.getActivation().getValidFrom())));
}
if (ActivationUtil.hasValidTo(shadowType)) {
attributes.add(AttributeBuilder.build(OperationalAttributes.DISABLE_DATE_NAME, XmlTypeConverter.toMillis(shadowType.getActivation().getValidTo())));
}
if (ActivationUtil.hasLockoutStatus(shadowType)) {
attributes.add(AttributeBuilder.build(OperationalAttributes.LOCK_OUT_NAME, ActivationUtil.isLockedOut(shadowType)));
}
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("ICF attributes after conversion:\n{}", ConnIdUtil.dump(attributes));
}
} catch (SchemaException | RuntimeException ex) {
result.recordFatalError("Error while converting resource object attributes. Reason: " + ex.getMessage(), ex);
throw new SchemaException("Error while converting resource object attributes. Reason: " + ex.getMessage(), ex);
}
if (attributes == null) {
result.recordFatalError("Couldn't set attributes for icf.");
throw new IllegalStateException("Couldn't set attributes for icf.");
}
List<String> icfAuxiliaryObjectClasses = new ArrayList<>();
for (QName auxiliaryObjectClass : shadowType.getAuxiliaryObjectClass()) {
icfAuxiliaryObjectClasses.add(connIdNameMapper.objectClassToIcf(auxiliaryObjectClass, resourceSchemaNamespace, connectorType, false).getObjectClassValue());
}
if (!icfAuxiliaryObjectClasses.isEmpty()) {
AttributeBuilder ab = new AttributeBuilder();
ab.setName(PredefinedAttributes.AUXILIARY_OBJECT_CLASS_NAME);
ab.addValue(icfAuxiliaryObjectClasses);
attributes.add(ab.build());
}
OperationOptionsBuilder operationOptionsBuilder = new OperationOptionsBuilder();
OperationOptions options = operationOptionsBuilder.build();
checkAndExecuteAdditionalOperation(reporter, additionalOperations, BeforeAfterType.BEFORE, result);
OperationResult connIdResult = result.createSubresult(ConnectorFacade.class.getName() + ".create");
connIdResult.addArbitraryObjectAsParam("objectClass", icfObjectClass);
connIdResult.addArbitraryCollectionAsParam("auxiliaryObjectClasses", icfAuxiliaryObjectClasses);
connIdResult.addArbitraryCollectionAsParam("attributes", attributes);
connIdResult.addArbitraryObjectAsParam("options", options);
connIdResult.addContext("connector", connIdConnectorFacade.getClass());
Uid uid = null;
try {
// CALL THE ICF FRAMEWORK
InternalMonitor.recordConnectorOperation("create");
// TODO provide object name
recordIcfOperationStart(reporter, ProvisioningOperation.ICF_CREATE, ocDef, null);
uid = connIdConnectorFacade.create(icfObjectClass, attributes, options);
recordIcfOperationEnd(reporter, ProvisioningOperation.ICF_CREATE, ocDef, uid);
} catch (Throwable ex) {
// TODO name
recordIcfOperationEnd(reporter, ProvisioningOperation.ICF_CREATE, ocDef, ex, null);
Throwable midpointEx = processIcfException(ex, this, connIdResult);
result.computeStatus("Add object failed");
// exception
if (midpointEx instanceof ObjectAlreadyExistsException) {
throw (ObjectAlreadyExistsException) midpointEx;
} else if (midpointEx instanceof CommunicationException) {
// result.muteError();
throw (CommunicationException) midpointEx;
} else if (midpointEx instanceof GenericFrameworkException) {
throw (GenericFrameworkException) midpointEx;
} else if (midpointEx instanceof SchemaException) {
throw (SchemaException) midpointEx;
} else if (midpointEx instanceof ConfigurationException) {
throw (ConfigurationException) midpointEx;
} else if (midpointEx instanceof RuntimeException) {
throw (RuntimeException) midpointEx;
} else if (midpointEx instanceof Error) {
throw (Error) midpointEx;
} else {
throw new SystemException("Got unexpected exception: " + ex.getClass().getName() + ": " + ex.getMessage(), ex);
}
}
checkAndExecuteAdditionalOperation(reporter, additionalOperations, BeforeAfterType.AFTER, result);
if (uid == null || uid.getUidValue() == null || uid.getUidValue().isEmpty()) {
connIdResult.recordFatalError("ICF did not returned UID after create");
result.computeStatus("Add object failed");
throw new GenericFrameworkException("ICF did not returned UID after create");
}
Collection<ResourceAttribute<?>> identifiers = ConnIdUtil.convertToIdentifiers(uid, attributesContainer.getDefinition().getComplexTypeDefinition(), resourceSchema);
for (ResourceAttribute<?> identifier : identifiers) {
attributesContainer.getValue().addReplaceExisting(identifier);
}
connIdResult.recordSuccess();
result.recordSuccess();
return AsynchronousOperationReturnValue.wrap(attributesContainer.getAttributes(), result);
}
Aggregations