use of com.evolveum.midpoint.prism.delta.ItemDelta in project midpoint by Evolveum.
the class GenericErrorHandler method handleError.
// @Autowired
// private OperationFinisher operationFinisher;
@Override
public <T extends ShadowType> T handleError(T shadow, FailedOperation op, Exception ex, boolean doDiscovery, boolean compensate, Task task, OperationResult parentResult) throws SchemaException, GenericFrameworkException, CommunicationException, ObjectNotFoundException, ObjectAlreadyExistsException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException {
if (!doDiscovery) {
parentResult.recordFatalError(ex);
if (ex instanceof GenericFrameworkException) {
throw (GenericFrameworkException) ex;
} else {
throw new GenericFrameworkException(ex.getMessage(), ex);
}
}
// OperationResult result = OperationResult.createOperationResult(shadow.getResult());
String operation = (shadow.getFailedOperationType() == null ? "null" : shadow.getFailedOperationType().name());
OperationResult result = parentResult.createSubresult(COMPENSATE_OPERATION);
result.addContext("compensatedOperation", operation);
result.addContext("operationType", op.name());
result.addParam("shadow", shadow);
result.addParam("currentOperation", op);
result.addParam("reconciled", true);
switch(op) {
case GET:
if (ShadowUtil.isDead(shadow) || ResourceTypeUtil.isDown(shadow.getResource()) || !compensate) {
result.recordStatus(OperationResultStatus.PARTIAL_ERROR, "Unable to get object from the resource. Probably it has not been created yet because of previous unavailability of the resource.");
result.computeStatus();
shadow.setFetchResult(parentResult.createOperationResultType());
return shadow;
}
if (shadow.getFailedOperationType() == null) {
String message = "Generic error in the connector. Can't process shadow " + ObjectTypeUtil.toShortString(shadow) + ": " + ex.getMessage();
result.recordFatalError(message, ex);
throw new GenericFrameworkException(message, ex);
}
try {
//ProvisioningOperationOptions.createCompletePostponed(false);
provisioningService.refreshShadow(shadow.asPrismObject(), null, task, result);
result.computeStatus();
if (result.isSuccess()) {
LOGGER.trace("Postponed operation was finished successfully while getting shadow. Getting new object.");
PrismObject prismShadow = provisioningService.getObject(shadow.getClass(), shadow.getOid(), null, task, result);
if (!prismShadow.hasCompleteDefinition()) {
LOGGER.trace("applying definitions to shadow");
provisioningService.applyDefinition(prismShadow, task, result);
}
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Got {} after finishing postponed operation.", prismShadow.debugDump());
}
shadow = (T) prismShadow.asObjectable();
}
// } catch(Exception e){
// result.recordFatalError("Could not finish operation " + operation + ". Reason: " + e.getMessage()));
// // just throw the origin exception
// throw new GenericFrameworkException(ex);
} finally {
result.computeStatus();
}
return shadow;
case MODIFY:
if (shadow.getFailedOperationType() == null) {
String message = "Generic error in the connector. Can't process shadow " + ObjectTypeUtil.toShortString(shadow) + ". ";
result.recordFatalError(message, ex);
throw new GenericFrameworkException(message, ex);
}
// get the modifications from the shadow before the account
// is created, because after successful creation of account,
// the modification will be lost
Collection<? extends ItemDelta> modifications = null;
if (shadow.getObjectChange() != null) {
ObjectDeltaType deltaType = shadow.getObjectChange();
modifications = DeltaConvertor.toModifications(deltaType.getItemDelta(), shadow.asPrismObject().getDefinition());
}
PropertyDelta.applyTo(modifications, shadow.asPrismObject());
provisioningService.refreshShadow(shadow.asPrismObject(), null, task, result);
result.computeStatus();
if (!result.isSuccess()) {
// account wasn't created, probably resource is
// still down, or there is other reason.just save the
// pending modifications to the shadow in the
// repository..next time by processing this shadow, we can try again
// TODO: probably there is a need to union current changes with previous
ConstraintsChecker.onShadowModifyOperation(modifications);
cacheRepositoryService.modifyObject(ShadowType.class, shadow.getOid(), modifications, result);
result.recordHandledError("Modifications not applied to the object, because resource is unreachable. They are stored to the shadow and will be applied when the resource goes online.");
}
return shadow;
case DELETE:
cacheRepositoryService.deleteObject(shadow.getClass(), shadow.getOid(), result);
result.recordStatus(OperationResultStatus.HANDLED_ERROR, "Object has been not created on the resource yet. Shadow deleted from the repository");
return shadow;
default:
result.recordFatalError("Can't process " + ObjectTypeUtil.toShortString(shadow) + ": " + ex.getMessage(), ex);
if (shadow.getOid() == null) {
throw new GenericFrameworkException("Can't process " + ObjectTypeUtil.toShortString(shadow) + ": " + ex.getMessage(), ex);
}
Collection<ItemDelta> modification = createAttemptModification(shadow, null);
ConstraintsChecker.onShadowModifyOperation(modification);
cacheRepositoryService.modifyObject(shadow.asPrismObject().getCompileTimeClass(), shadow.getOid(), modification, parentResult);
String message = "Can't process " + ObjectTypeUtil.toShortString(shadow) + ". ";
result.recordFatalError(message, ex);
throw new GenericFrameworkException(message, ex);
}
}
use of com.evolveum.midpoint.prism.delta.ItemDelta in project midpoint by Evolveum.
the class CertificationCaseHelper method addOrDeleteCases.
protected List<Long> addOrDeleteCases(Session session, String campaignOid, Collection<? extends ItemDelta> modifications) throws SchemaException, DtoTranslationException {
final ItemPath casePath = new ItemPath(AccessCertificationCampaignType.F_CASE);
boolean replacePresent = false;
List<Long> affectedIds = new ArrayList<>();
for (ItemDelta delta : modifications) {
ItemPath deltaPath = delta.getPath();
if (!casePath.isSubPathOrEquivalent(deltaPath)) {
throw new IllegalStateException("Wrong campaign delta sneaked into updateCampaignCases: class=" + delta.getClass() + ", path=" + deltaPath);
}
if (deltaPath.size() == 1) {
if (delta.getValuesToDelete() != null) {
// todo do 'bulk' delete like delete from ... where oid=? and id in (...)
for (PrismContainerValue value : (Collection<PrismContainerValue>) delta.getValuesToDelete()) {
Long id = value.getId();
if (id == null) {
throw new SchemaException("Couldn't delete certification case with null id");
}
affectedIds.add(id);
// TODO couldn't this cascading be done by hibernate itself?
Integer integerCaseId = RUtil.toInteger(id);
// Query deleteCaseReferences = session.createSQLQuery("delete from " + RCertCaseReference.TABLE +
// " where owner_owner_oid=:oid and owner_id=:id");
// deleteCaseReferences.setString("oid", campaignOid);
// deleteCaseReferences.setInteger("id", integerCaseId);
// deleteCaseReferences.executeUpdate();
Query deleteWorkItemReferences = session.createSQLQuery("delete from " + RCertWorkItemReference.TABLE + " where owner_owner_owner_oid=:oid and owner_owner_id=:id");
deleteWorkItemReferences.setString("oid", campaignOid);
deleteWorkItemReferences.setInteger("id", integerCaseId);
deleteWorkItemReferences.executeUpdate();
Query deleteCaseWorkItems = session.createSQLQuery("delete from " + RAccessCertificationWorkItem.TABLE + " where owner_owner_oid=:oid and owner_id=:id");
deleteCaseWorkItems.setString("oid", campaignOid);
deleteCaseWorkItems.setInteger("id", integerCaseId);
deleteCaseWorkItems.executeUpdate();
Query deleteCase = session.getNamedQuery("delete.campaignCase");
deleteCase.setString("oid", campaignOid);
deleteCase.setInteger("id", integerCaseId);
deleteCase.executeUpdate();
}
}
// So it's safest not to provide any IDs by the client
if (delta.getValuesToAdd() != null) {
int currentId = generalHelper.findLastIdInRepo(session, campaignOid, "get.campaignCaseLastId") + 1;
addCertificationCampaignCases(session, campaignOid, delta.getValuesToAdd(), currentId, affectedIds);
}
if (delta.getValuesToReplace() != null) {
deleteCertificationCampaignCases(session, campaignOid);
addCertificationCampaignCases(session, campaignOid, delta.getValuesToReplace(), 1, affectedIds);
replacePresent = true;
}
}
}
return replacePresent ? null : affectedIds;
}
use of com.evolveum.midpoint.prism.delta.ItemDelta in project midpoint by Evolveum.
the class CertificationCaseHelper method filterCampaignCaseModifications.
public <T extends ObjectType> Collection<? extends ItemDelta> filterCampaignCaseModifications(Class<T> type, Collection<? extends ItemDelta> modifications) {
Collection<ItemDelta> caseDelta = new ArrayList<>();
if (!AccessCertificationCampaignType.class.equals(type)) {
return caseDelta;
}
ItemPath casePath = new ItemPath(AccessCertificationCampaignType.F_CASE);
for (ItemDelta delta : modifications) {
ItemPath path = delta.getPath();
if (path.isEmpty()) {
throw new UnsupportedOperationException("Certification campaign cannot be modified via empty-path modification");
} else if (path.equivalent(casePath)) {
caseDelta.add(delta);
} else if (path.isSuperPath(casePath)) {
// like case[id]/xxx
caseDelta.add(delta);
}
}
modifications.removeAll(caseDelta);
return caseDelta;
}
use of com.evolveum.midpoint.prism.delta.ItemDelta in project midpoint by Evolveum.
the class LookupTableHelper method filterLookupTableModifications.
public <T extends ObjectType> Collection<? extends ItemDelta> filterLookupTableModifications(Class<T> type, Collection<? extends ItemDelta> modifications) {
Collection<ItemDelta> tableDelta = new ArrayList<>();
if (!LookupTableType.class.equals(type)) {
return tableDelta;
}
ItemPath rowPath = new ItemPath(LookupTableType.F_ROW);
for (ItemDelta delta : modifications) {
ItemPath path = delta.getPath();
if (path.isEmpty()) {
throw new UnsupportedOperationException("Lookup table cannot be modified via empty-path modification");
} else if (path.equivalent(rowPath)) {
tableDelta.add(delta);
} else if (path.isSuperPath(rowPath)) {
// should be row[id]/xxx where xxx=key|value|label?
List<ItemPathSegment> segments = path.getSegments();
if (segments.size() != 3 || !(segments.get(1) instanceof IdItemPathSegment) || !(segments.get(2) instanceof NameItemPathSegment)) {
throw new UnsupportedOperationException("Unsupported modification path for lookup tables: " + path);
}
tableDelta.add(delta);
}
}
modifications.removeAll(tableDelta);
return tableDelta;
}
use of com.evolveum.midpoint.prism.delta.ItemDelta in project midpoint by Evolveum.
the class TestOrgStruct method test404JackChangeMinistryOfOffenseManagerToMemberByAddingRemovingAssignment.
@Test
public void test404JackChangeMinistryOfOffenseManagerToMemberByAddingRemovingAssignment() throws Exception {
final String TEST_NAME = "test404JackChangeMinistryOfOffenseManagerToMemberByAddingRemovingAssignment";
TestUtil.displayTestTile(this, TEST_NAME);
Task task = taskManager.createTaskInstance(TestOrgStruct.class.getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
PrismObject<UserType> jack = getUser(USER_JACK_OID);
Collection<ItemDelta<?, ?>> modifications = new ArrayList<>();
modifications.add(createAssignmentModification(ORG_MINISTRY_OF_OFFENSE_OID, OrgType.COMPLEX_TYPE, SchemaConstants.ORG_MANAGER, null, null, false));
modifications.add(createAssignmentModification(ORG_MINISTRY_OF_OFFENSE_OID, OrgType.COMPLEX_TYPE, null, null, null, true));
ObjectDelta<UserType> userDelta = ObjectDelta.createModifyDelta(USER_JACK_OID, modifications, UserType.class, prismContext);
Collection<ObjectDelta<? extends ObjectType>> deltas = MiscSchemaUtil.createCollection(userDelta);
// WHEN
modelService.executeChanges(deltas, null, task, result);
// THEN
PrismObject<UserType> userJack = getUser(USER_JACK_OID);
display("User jack after", userJack);
assertAssignedOrgs(userJack, ORG_MINISTRY_OF_OFFENSE_OID);
// because of object template and the modification
assertAssignedOrg(userJack, ORG_MINISTRY_OF_OFFENSE_OID, null);
assertHasOrgs(userJack, ORG_MINISTRY_OF_OFFENSE_OID);
assertHasOrg(userJack, ORG_MINISTRY_OF_OFFENSE_OID, null);
// Postcondition
assertMonkeyIslandOrgSanity();
}
Aggregations