use of com.evolveum.midpoint.schema.reporting.ConnIdOperation in project midpoint by Evolveum.
the class ConnectorInstanceConnIdImpl method count.
@Override
public int count(ResourceObjectDefinition objectDefinition, final ObjectQuery query, PagedSearchCapabilityType pagedSearchCapabilityType, UcfExecutionContext ctx, OperationResult parentResult) throws CommunicationException, GenericFrameworkException, SchemaException, UnsupportedOperationException {
// Result type for this operation
final OperationResult result = parentResult.createSubresult(ConnectorInstance.class.getName() + ".count");
result.addArbitraryObjectAsParam("objectClass", objectDefinition);
result.addContext("connector", connectorType);
if (objectDefinition == null) {
result.recordFatalError("Object class not defined");
throw new IllegalArgumentException("objectClass not defined");
}
ObjectClass icfObjectClass = objectClassToConnId(objectDefinition);
final boolean useConnectorPaging = pagedSearchCapabilityType != null;
if (!useConnectorPaging) {
throw new UnsupportedOperationException("ConnectorInstanceIcfImpl.count operation is supported only in combination with connector-implemented paging");
}
OperationOptionsBuilder optionsBuilder = new OperationOptionsBuilder();
optionsBuilder.setAttributesToGet(Name.NAME);
optionsBuilder.setPagedResultsOffset(1);
optionsBuilder.setPageSize(1);
if (pagedSearchCapabilityType.getDefaultSortField() != null) {
String orderByIcfName = connIdNameMapper.convertAttributeNameToConnId(pagedSearchCapabilityType.getDefaultSortField(), objectDefinition, "(default sorting field)");
boolean isAscending = pagedSearchCapabilityType.getDefaultSortDirection() != OrderDirectionType.DESCENDING;
optionsBuilder.setSortKeys(new SortKey(orderByIcfName, isAscending));
}
OperationOptions options = optionsBuilder.build();
// Connector operation cannot create result for itself, so we need to
// create result for it
OperationResult icfResult = result.createSubresult(ConnectorFacade.class.getName() + ".search");
icfResult.addArbitraryObjectAsParam("objectClass", icfObjectClass);
icfResult.addContext("connector", connIdConnectorFacade.getClass());
int retval;
InternalMonitor.recordConnectorOperation("search");
ConnIdOperation operation = recordIcfOperationStart(ctx, ProvisioningOperation.ICF_SEARCH, objectDefinition);
try {
Filter filter = convertFilterToIcf(query, objectDefinition);
final Holder<Integer> fetched = new Holder<>(0);
ResultsHandler connIdHandler = new ResultsHandler() {
@Override
public boolean handle(ConnectorObject connectorObject) {
// actually, this should execute at most once
fetched.setValue(fetched.getValue() + 1);
return false;
}
@Override
public String toString() {
return "(midPoint counting result handler)";
}
};
LOGGER.trace("Invoking ConnId search operation (to count objects): {}", operation);
SearchResult searchResult = connIdConnectorFacade.search(icfObjectClass, filter, connIdHandler, options);
recordIcfOperationEnd(ctx, operation, null);
if (searchResult == null || searchResult.getRemainingPagedResults() == -1) {
throw new UnsupportedOperationException("Connector does not seem to support paged searches or does not provide object count information");
} else {
retval = fetched.getValue() + searchResult.getRemainingPagedResults();
}
icfResult.recordSuccess();
} catch (IntermediateException inex) {
recordIcfOperationEnd(ctx, operation, inex);
SchemaException ex = (SchemaException) inex.getCause();
icfResult.recordFatalError(ex);
result.recordFatalError(ex);
throw ex;
} catch (UnsupportedOperationException uoe) {
recordIcfOperationEnd(ctx, operation, uoe);
icfResult.recordFatalError(uoe);
result.recordFatalError(uoe);
throw uoe;
} catch (Throwable ex) {
recordIcfOperationEnd(ctx, operation, ex);
Throwable midpointEx = processConnIdException(ex, this, icfResult);
result.computeStatus();
// exception
if (midpointEx instanceof CommunicationException) {
throw (CommunicationException) midpointEx;
} else if (midpointEx instanceof GenericFrameworkException) {
throw (GenericFrameworkException) midpointEx;
} else if (midpointEx instanceof SchemaException) {
throw (SchemaException) 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);
}
}
if (result.isUnknown()) {
result.recordSuccess();
}
return retval;
}
use of com.evolveum.midpoint.schema.reporting.ConnIdOperation in project midpoint by Evolveum.
the class SearchExecutor method executeConnIdSearch.
private SearchResult executeConnIdSearch(OperationOptions connIdOptions, OperationResult parentResult) throws CommunicationException, ObjectNotFoundException, GenericFrameworkException, SchemaException, SecurityViolationException {
// Connector operation cannot create result for itself, so we need to create result for it
OperationResult result = parentResult.createSubresult(ConnectorFacade.class.getName() + ".search");
result.addArbitraryObjectAsParam("objectClass", icfObjectClass);
SearchResult connIdSearchResult;
InternalMonitor.recordConnectorOperation("search");
ConnIdOperation operation = recordIcfOperationStart();
ResultsHandler connIdHandler = new SearchResultsHandler(operation, result);
try {
LOGGER.trace("Executing ConnId search operation: {}", operation);
connIdSearchResult = connectorInstance.getConnIdConnectorFacade().search(icfObjectClass, connIdFilter, connIdHandler, connIdOptions);
recordIcfOperationEnd(operation, null);
result.recordSuccess();
} catch (IntermediateException inEx) {
Throwable ex = inEx.getCause();
recordIcfOperationEnd(operation, ex);
result.recordFatalError(ex);
throwProperException(ex, ex);
throw new AssertionError("should not get here");
} catch (Throwable ex) {
recordIcfOperationEnd(operation, ex);
Throwable midpointEx = processConnIdException(ex, connectorInstance, result);
throwProperException(midpointEx, ex);
throw new AssertionError("should not get here");
} finally {
result.computeStatusIfUnknown();
}
return connIdSearchResult;
}
use of com.evolveum.midpoint.schema.reporting.ConnIdOperation in project midpoint by Evolveum.
the class UcfExecutionContext method recordIcfOperationStart.
@NotNull
public ConnIdOperation recordIcfOperationStart(@NotNull ProvisioningOperation operationKind, @Nullable ResourceObjectDefinition objectClassDef, @Nullable String uid) {
ConnIdOperation operation = ConnIdOperation.ConnIdOperationBuilder.aConnIdOperation().withIdentifier(lightweightIdentifierGenerator.generate().toString()).withOperation(operationKind).withResourceRef(ObjectTypeUtil.createObjectRef(resource)).withObjectClassDef(objectClassDef != null ? objectClassDef.getObjectClassDefinition() : null).withUid(uid).build();
LOGGER.trace("recordIcfOperationStart: {} in {}", operation, task);
if (currentOperation != null) {
LOGGER.warn("Unfinished operation: {}", currentOperation);
}
currentOperation = operation;
if (task != null) {
task.onConnIdOperationStart(operation);
} else {
reportNoTask(operation);
}
String object = "";
if (uid != null) {
object = " " + uid;
}
recordState("Starting " + operationKind + " of " + getObjectClassName(objectClassDef) + object + " on " + getResourceName());
return operation;
}
use of com.evolveum.midpoint.schema.reporting.ConnIdOperation in project midpoint by Evolveum.
the class ConnectorInstanceConnIdImpl method fetchConnectorObject.
/**
* Returns null if nothing is found.
*/
private ConnectorObject fetchConnectorObject(UcfExecutionContext reporter, ResourceObjectDefinition objectDefinition, ObjectClass icfObjectClass, Uid uid, OperationOptions options, OperationResult parentResult) throws ObjectNotFoundException, CommunicationException, GenericFrameworkException, SecurityViolationException, SchemaException, ConfigurationException {
// Connector operation cannot create result for itself, so we need to
// create result for it
OperationResult icfResult = parentResult.createMinorSubresult(ConnectorFacade.class.getName() + ".getObject");
icfResult.addArbitraryObjectAsParam("objectClass", icfObjectClass);
icfResult.addParam("uid", uid.getUidValue());
icfResult.addArbitraryObjectAsParam("options", options);
icfResult.addContext("connector", connIdConnectorFacade.getClass());
InternalMonitor.recordConnectorOperation("getObject");
ConnIdOperation operation = recordIcfOperationStart(reporter, ProvisioningOperation.ICF_GET, objectDefinition, uid);
LOGGER.trace("Fetching connector object ObjectClass={}, UID={}, operation id={}, options={}", icfObjectClass, uid, getIdentifier(operation), ConnIdUtil.dumpOptionsLazily(options));
ConnectorObject co;
try {
// Invoke the ConnId connector
co = connIdConnectorFacade.getObject(icfObjectClass, uid, options);
recordIcfOperationEnd(reporter, operation, null);
icfResult.recordSuccess();
} catch (Throwable ex) {
recordIcfOperationEnd(reporter, operation, ex);
String desc = this.getHumanReadableName() + " while getting object identified by ConnId UID '" + uid.getUidValue() + "'";
Throwable midpointEx = processConnIdException(ex, desc, icfResult);
icfResult.computeStatus("Add object failed");
// exception
if (midpointEx instanceof CommunicationException) {
icfResult.muteError();
throw (CommunicationException) midpointEx;
} else if (midpointEx instanceof GenericFrameworkException) {
throw (GenericFrameworkException) midpointEx;
} else if (midpointEx instanceof ConfigurationException) {
throw (ConfigurationException) midpointEx;
} else if (midpointEx instanceof SecurityViolationException) {
throw (SecurityViolationException) midpointEx;
} else if (midpointEx instanceof ObjectNotFoundException) {
LOGGER.trace("Got ObjectNotFoundException while looking for resource object ConnId UID: {}", uid);
return null;
} else if (midpointEx instanceof RuntimeException) {
throw (RuntimeException) midpointEx;
} else if (midpointEx instanceof Error) {
// This should not happen. But some connectors are very strange.
throw new SystemException("ERROR: " + midpointEx.getClass().getName() + ": " + midpointEx.getMessage(), midpointEx);
} else {
throw new SystemException(midpointEx.getClass().getName() + ": " + midpointEx.getMessage(), midpointEx);
}
}
return co;
}
use of com.evolveum.midpoint.schema.reporting.ConnIdOperation in project midpoint by Evolveum.
the class ConnectorInstanceConnIdImpl method modifyObjectUpdate.
/**
* Modifies object by using old add/delete/replace attribute operations.
*/
private AsynchronousOperationReturnValue<Collection<PropertyModificationOperation>> modifyObjectUpdate(ResourceObjectIdentification identification, ObjectClass objClass, Uid uid, PrismObject<ShadowType> shadow, Collection<Operation> changes, ConnectorOperationOptions options, UcfExecutionContext reporter, OperationResult result) throws ObjectNotFoundException, CommunicationException, GenericFrameworkException, SchemaException, SecurityViolationException, ObjectAlreadyExistsException, PolicyViolationException {
ResourceObjectDefinition objectClassDef = identification.getResourceObjectDefinition();
String originalUid = uid.getUidValue();
UpdateModificationConverter converter = new UpdateModificationConverter();
converter.setChanges(changes);
converter.setConnectorDescription(description);
converter.setConnectorType(connectorType);
converter.setConnIdNameMapper(connIdNameMapper);
converter.setObjectDefinition(objectClassDef);
converter.setProtector(protector);
converter.setResourceSchema(rawResourceSchema);
try {
converter.convert();
} catch (SchemaException | RuntimeException | Error e) {
result.recordFatalError(e);
throw e;
}
LOGGER.trace("converted attributes:\n{}", converter.debugDumpLazily(1));
// Needs three complete try-catch blocks because we need to create
// icfResult for each operation
// and handle the faults individually
OperationResult connIdResult;
Set<Attribute> attributesToAdd = converter.getAttributesToAdd();
if (!attributesToAdd.isEmpty()) {
OperationOptions connIdOptions = createConnIdOptions(options, changes);
connIdResult = result.createSubresult(ConnectorFacade.class.getName() + ".addAttributeValues");
connIdResult.addArbitraryObjectAsParam("objectClass", objectClassDef);
connIdResult.addParam("uid", uid.getUidValue());
connIdResult.addArbitraryObjectAsParam("attributes", attributesToAdd);
connIdResult.addArbitraryObjectAsParam("options", connIdOptions);
connIdResult.addContext("connector", connIdConnectorFacade.getClass());
InternalMonitor.recordConnectorOperation("addAttributeValues");
InternalMonitor.recordConnectorModification("addAttributeValues");
@Nullable ConnIdOperation operation = recordIcfOperationStart(reporter, ProvisioningOperation.ICF_UPDATE, objectClassDef, uid);
LOGGER.trace("Invoking ConnId addAttributeValues(), objectclass={}, uid={}, operation id={}, attributes: {}", objClass, uid, getIdentifier(operation), lazy(() -> dumpAttributes(attributesToAdd)));
try {
uid = connIdConnectorFacade.addAttributeValues(objClass, uid, attributesToAdd, connIdOptions);
recordIcfOperationEnd(reporter, operation, null);
connIdResult.recordSuccess();
} catch (Throwable ex) {
recordIcfOperationEnd(reporter, operation, ex);
String desc = this.getHumanReadableName() + " while adding attribute values to object identified by ConnId UID '" + uid.getUidValue() + "'";
Throwable midpointEx = processConnIdException(ex, desc, connIdResult);
result.computeStatus("Adding attribute values failed");
// exception
if (midpointEx instanceof ObjectNotFoundException) {
throw (ObjectNotFoundException) midpointEx;
} else if (midpointEx instanceof CommunicationException) {
// in this situation this is not a critical error, becasue we know to handle it..so mute the error and sign it as expected
result.muteError();
connIdResult.muteError();
throw (CommunicationException) midpointEx;
} else if (midpointEx instanceof GenericFrameworkException) {
throw (GenericFrameworkException) midpointEx;
} else if (midpointEx instanceof SchemaException) {
throw (SchemaException) midpointEx;
} else if (midpointEx instanceof AlreadyExistsException) {
throw (AlreadyExistsException) midpointEx;
} else if (midpointEx instanceof RuntimeException) {
throw (RuntimeException) midpointEx;
} else if (midpointEx instanceof SecurityViolationException) {
throw (SecurityViolationException) midpointEx;
} else if (midpointEx instanceof PolicyViolationException) {
throw (PolicyViolationException) midpointEx;
} else if (midpointEx instanceof Error) {
throw (Error) midpointEx;
} else {
throw new SystemException("Got unexpected exception: " + ex.getClass().getName() + ": " + ex.getMessage(), ex);
}
}
}
Set<Attribute> attributesToUpdate = converter.getAttributesToUpdate();
if (!attributesToUpdate.isEmpty()) {
OperationOptions connIdOptions = createConnIdOptions(options, changes);
connIdResult = result.createSubresult(ConnectorFacade.class.getName() + ".update");
connIdResult.addArbitraryObjectAsParam("objectClass", objectClassDef);
connIdResult.addParam("uid", uid == null ? "null" : uid.getUidValue());
connIdResult.addArbitraryObjectAsParam("attributes", attributesToUpdate);
connIdResult.addArbitraryObjectAsParam("options", connIdOptions);
connIdResult.addContext("connector", connIdConnectorFacade.getClass());
InternalMonitor.recordConnectorOperation("update");
InternalMonitor.recordConnectorModification("update");
@Nullable ConnIdOperation operation = recordIcfOperationStart(reporter, ProvisioningOperation.ICF_UPDATE, objectClassDef, uid);
LOGGER.trace("Invoking ConnId update(), objectclass={}, uid={}, operation id={}, attributes: {}", objClass, uid, getIdentifier(operation), lazy(() -> dumpAttributes(attributesToUpdate)));
try {
uid = connIdConnectorFacade.update(objClass, uid, attributesToUpdate, connIdOptions);
recordIcfOperationEnd(reporter, operation, null);
connIdResult.recordSuccess();
} catch (Throwable ex) {
recordIcfOperationEnd(reporter, operation, ex);
String desc = this.getHumanReadableName() + " while updating object identified by ConnId UID '" + uid.getUidValue() + "'";
Throwable midpointEx = processConnIdException(ex, desc, connIdResult);
result.computeStatus("Update failed");
// exception
if (midpointEx instanceof ObjectNotFoundException) {
throw (ObjectNotFoundException) midpointEx;
} else if (midpointEx instanceof CommunicationException) {
// in this situation this is not a critical error, becasue we know to handle it..so mute the error and sign it as expected
result.muteError();
connIdResult.muteError();
throw (CommunicationException) midpointEx;
} else if (midpointEx instanceof GenericFrameworkException) {
throw (GenericFrameworkException) midpointEx;
} else if (midpointEx instanceof SchemaException) {
throw (SchemaException) midpointEx;
} else if (midpointEx instanceof ObjectAlreadyExistsException) {
throw (ObjectAlreadyExistsException) midpointEx;
} else if (midpointEx instanceof RuntimeException) {
throw (RuntimeException) midpointEx;
} else if (midpointEx instanceof SecurityViolationException) {
throw (SecurityViolationException) midpointEx;
} else if (midpointEx instanceof PolicyViolationException) {
throw (PolicyViolationException) midpointEx;
} else if (midpointEx instanceof Error) {
throw (Error) midpointEx;
} else {
throw new SystemException("Got unexpected exception: " + ex.getClass().getName() + ": " + ex.getMessage(), ex);
}
}
}
Set<Attribute> attributesToRemove = converter.getAttributesToRemove();
if (!attributesToRemove.isEmpty()) {
OperationOptions connIdOptions = createConnIdOptions(options, changes);
connIdResult = result.createSubresult(ConnectorFacade.class.getName() + ".removeAttributeValues");
connIdResult.addArbitraryObjectAsParam("objectClass", objectClassDef);
connIdResult.addParam("uid", uid.getUidValue());
connIdResult.addArbitraryObjectAsParam("attributes", attributesToRemove);
connIdResult.addArbitraryObjectAsParam("options", connIdOptions);
connIdResult.addContext("connector", connIdConnectorFacade.getClass());
InternalMonitor.recordConnectorOperation("removeAttributeValues");
InternalMonitor.recordConnectorModification("removeAttributeValues");
@Nullable ConnIdOperation operation = recordIcfOperationStart(reporter, ProvisioningOperation.ICF_UPDATE, objectClassDef, uid);
LOGGER.trace("Invoking ConnId removeAttributeValues(), objectclass={}, uid={}, operation id={}, attributes: {}", objClass, uid, getIdentifier(operation), lazy(() -> dumpAttributes(attributesToRemove)));
try {
uid = connIdConnectorFacade.removeAttributeValues(objClass, uid, attributesToRemove, connIdOptions);
recordIcfOperationEnd(reporter, operation, null);
connIdResult.recordSuccess();
} catch (Throwable ex) {
recordIcfOperationEnd(reporter, operation, ex);
String desc = this.getHumanReadableName() + " while removing attribute values from object identified by ConnId UID '" + uid.getUidValue() + "'";
Throwable midpointEx = processConnIdException(ex, desc, connIdResult);
result.computeStatus("Removing attribute values failed");
// exception
if (midpointEx instanceof ObjectNotFoundException) {
throw (ObjectNotFoundException) midpointEx;
} else if (midpointEx instanceof CommunicationException) {
// in this situation this is not a critical error, becasue we know to handle it..so mute the error and sign it as expected
result.muteError();
connIdResult.muteError();
throw (CommunicationException) midpointEx;
} else if (midpointEx instanceof GenericFrameworkException) {
throw (GenericFrameworkException) midpointEx;
} else if (midpointEx instanceof SchemaException) {
throw (SchemaException) midpointEx;
} else if (midpointEx instanceof ObjectAlreadyExistsException) {
throw (ObjectAlreadyExistsException) midpointEx;
} else if (midpointEx instanceof RuntimeException) {
throw (RuntimeException) midpointEx;
} else if (midpointEx instanceof SecurityViolationException) {
throw (SecurityViolationException) midpointEx;
} else if (midpointEx instanceof PolicyViolationException) {
throw (PolicyViolationException) midpointEx;
} else if (midpointEx instanceof Error) {
throw (Error) midpointEx;
} else {
throw new SystemException("Got unexpected exception: " + ex.getClass().getName() + ": " + ex.getMessage(), ex);
}
}
}
result.computeStatus();
Collection<PropertyModificationOperation> sideEffectChanges = new ArrayList<>();
if (!originalUid.equals(uid.getUidValue())) {
// UID was changed during the operation, this is most likely a rename
PropertyDelta<String> uidDelta = createUidDelta(uid, getUidDefinition(identification));
PropertyModificationOperation uidMod = new PropertyModificationOperation(uidDelta);
// TODO what about matchingRuleQName ?
sideEffectChanges.add(uidMod);
replaceUidValue(identification, uid);
}
return AsynchronousOperationReturnValue.wrap(sideEffectChanges, result);
}
Aggregations