use of com.evolveum.midpoint.schema.processor.ResourceObjectDefinition in project midpoint by Evolveum.
the class ConstraintsChecker method checkUniquenessByQuery.
private boolean checkUniquenessByQuery(PrismProperty<?> identifier, ObjectQuery query, OperationResult result) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException, ExpressionEvaluationException {
ResourceObjectDefinition resourceObjectDefinition = provisioningContext.getObjectDefinitionRequired();
ResourceType resourceType = provisioningContext.getResource();
if (useCache && Cache.isOk(resourceType.getOid(), shadowOid, resourceObjectDefinition.getTypeName(), identifier.getDefinition().getItemName(), identifier.getValues(), cacheConfigurationManager)) {
return true;
}
// Note that we should not call repository service directly here. The query values need to be normalized according to
// attribute matching rules.
Collection<SelectorOptions<GetOperationOptions>> options = SelectorOptions.createCollection(GetOperationOptions.createNoFetch());
List<PrismObject<ShadowType>> foundObjects = shadowsFacade.searchObjects(query, options, provisioningContext.getTask(), result);
LOGGER.trace("Uniqueness check of {} resulted in {} results:\n{}\nquery:\n{}", identifier, foundObjects.size(), foundObjects, query.debugDumpLazily(1));
if (foundObjects.isEmpty()) {
if (useCache) {
Cache.setOk(resourceType.getOid(), shadowOid, resourceObjectDefinition.getTypeName(), identifier.getDefinition().getItemName(), identifier.getValues());
}
return true;
}
if (foundObjects.size() > 1) {
LOGGER.error("Found {} objects with attribute {}:\n{}", foundObjects.size(), identifier.toHumanReadableString(), foundObjects);
if (LOGGER.isDebugEnabled()) {
for (PrismObject<ShadowType> foundObject : foundObjects) {
LOGGER.debug("Conflicting object:\n{}", foundObject.debugDump());
}
}
message("Found more than one object with attribute " + identifier.toHumanReadableString());
return false;
}
LOGGER.trace("Comparing {} and {}", foundObjects.get(0).getOid(), shadowOid);
boolean match = foundObjects.get(0).getOid().equals(shadowOid);
if (!match) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Found conflicting existing object with attribute " + identifier.toHumanReadableString() + ":\n" + foundObjects.get(0).debugDump());
}
message("Found conflicting existing object with attribute " + identifier.toHumanReadableString() + ": " + foundObjects.get(0));
match = !constraintViolationConfirmer.confirmViolation(foundObjects.get(0));
constraintsCheckingResult.setConflictingShadow(foundObjects.get(0));
// We do not cache "OK" here because the violation confirmer could depend on
// attributes/items that are not under our observations.
} else {
if (useCache) {
Cache.setOk(resourceType.getOid(), shadowOid, resourceObjectDefinition.getTypeName(), identifier.getDefinition().getItemName(), identifier.getValues());
}
return true;
}
return match;
}
use of com.evolveum.midpoint.schema.processor.ResourceObjectDefinition in project midpoint by Evolveum.
the class SearchHelper method countObjects.
public Integer countObjects(ObjectQuery query, Task task, final OperationResult result) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException {
ObjectFilter filter = query != null ? query.getFilter() : null;
ResourceShadowDiscriminator coordinates = ObjectQueryUtil.getCoordinates(filter);
// otherwise coordinates couldn't be found
assert query != null;
ProvisioningContext ctx = ctxFactory.createForCoordinates(coordinates, task, result);
ctx.assertDefinition();
definitionsHelper.applyDefinition(ctx, query);
ResourceObjectDefinition objectClassDef = ctx.getObjectDefinitionRequired();
ResourceType resourceType = ctx.getResource();
CountObjectsCapabilityType countObjectsCapabilityType = objectClassDef.getEffectiveCapability(CountObjectsCapabilityType.class, resourceType);
if (countObjectsCapabilityType == null) {
// Unable to count. Return null which means "I do not know"
LOGGER.trace("countObjects: cannot count (no counting capability)");
result.recordNotApplicableIfUnknown();
return null;
} else {
CountObjectsSimulateType simulate = countObjectsCapabilityType.getSimulate();
if (simulate == null) {
// We have native capability
LOGGER.trace("countObjects: counting with native count capability");
ConnectorInstance connector = ctx.getConnector(ReadCapabilityType.class, result);
try {
ObjectQuery attributeQuery = createAttributeQuery(query);
int count;
try {
count = connector.count(objectClassDef.getObjectClassDefinition(), attributeQuery, objectClassDef.getPagedSearches(resourceType), ctx.getUcfExecutionContext(), 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) {
LOGGER.trace("countObjects: simulating counting with paged search estimate");
if (!objectClassDef.isPagedSearchEnabled(resourceType)) {
throw new ConfigurationException("Configured count object capability to be simulated using a paged search but paged search capability is not present");
}
query = query.clone();
ObjectPaging paging = prismContext.queryFactory().createPaging();
// Explicitly set offset. This makes a difference for some resources.
// E.g. LDAP connector will detect presence of an offset and it will initiate VLV search which
// can estimate number of results. If no offset is specified then continuous/linear search is
// assumed (e.g. Simple Paged Results search). Such search does not have ability to estimate
// number of results.
paging.setOffset(0);
paging.setMaxSize(1);
query.setPaging(paging);
Collection<SelectorOptions<GetOperationOptions>> options = schemaService.getOperationOptionsBuilder().item(ShadowType.F_ASSOCIATION).dontRetrieve().build();
int count;
try {
count = countObjects(query, options, CountMethod.METADATA, task, result);
} catch (SchemaException | ObjectNotFoundException | ConfigurationException | SecurityViolationException e) {
result.recordFatalError(e);
throw e;
}
result.computeStatus();
result.cleanupResult();
return count;
} else if (simulate == CountObjectsSimulateType.SEQUENTIAL_SEARCH) {
// fix for MID-5204. as sequentialSearch option causes to fetch all resource objects,
// query paging is senseless here
query = query.clone();
query.setPaging(null);
LOGGER.trace("countObjects: simulating counting with sequential search (likely performance impact)");
Collection<SelectorOptions<GetOperationOptions>> options = schemaService.getOperationOptionsBuilder().item(ShadowType.F_ASSOCIATION).dontRetrieve().build();
int count = countObjects(query, options, CountMethod.COUNTING, task, result);
// TODO: better error handling
result.computeStatus();
result.cleanupResult();
return count;
} else {
throw new IllegalArgumentException("Unknown count capability simulate type " + simulate);
}
}
}
use of com.evolveum.midpoint.schema.processor.ResourceObjectDefinition in project midpoint by Evolveum.
the class ResourceObjectFound method addFakePrimaryIdentifierIfNeeded.
private void addFakePrimaryIdentifierIfNeeded() throws SchemaException {
ResourceObjectDefinition definition = ictx.ctx.getObjectDefinitionRequired();
ResourceAttributeContainer attrContainer = ShadowUtil.getOrCreateAttributesContainer(resourceObject, definition);
localBeans.fakeIdentifierGenerator.addFakePrimaryIdentifierIfNeeded(attrContainer, primaryIdentifierValue, definition);
}
use of com.evolveum.midpoint.schema.processor.ResourceObjectDefinition in project midpoint by Evolveum.
the class ResourceObjectReferenceResolver method resolvePrimaryIdentifiers.
/**
* Resolve primary identifier from a collection of identifiers that may contain only secondary identifiers.
*/
@SuppressWarnings("unchecked")
private ResourceObjectIdentification resolvePrimaryIdentifiers(ProvisioningContext ctx, ResourceObjectIdentification identification, OperationResult result) throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, ExpressionEvaluationException {
if (identification == null) {
return null;
}
if (identification.hasPrimaryIdentifiers()) {
return identification;
}
Collection<ResourceAttribute<?>> secondaryIdentifiers = (Collection<ResourceAttribute<?>>) identification.getSecondaryIdentifiers();
PrismObject<ShadowType> repoShadow = shadowManager.lookupShadowBySecondaryIds(ctx, secondaryIdentifiers, result);
if (repoShadow == null) {
// TODO: we should attempt resource search here
throw new ObjectNotFoundException("No repository shadow for " + secondaryIdentifiers + ", cannot resolve identifiers");
}
shadowsFacade.applyDefinition(repoShadow, ctx.getTask(), result);
PrismContainer<Containerable> attributesContainer = repoShadow.findContainer(ShadowType.F_ATTRIBUTES);
if (attributesContainer == null) {
throw new SchemaException("No attributes in " + repoShadow + ", cannot resolve identifiers " + secondaryIdentifiers);
}
ResourceObjectDefinition objDef = ctx.getObjectDefinitionRequired();
Collection primaryIdentifiers = new ArrayList<>();
for (PrismProperty<?> property : attributesContainer.getValue().getProperties()) {
if (objDef.isPrimaryIdentifier(property.getElementName())) {
ResourceAttributeDefinition<?> attrDef = objDef.findAttributeDefinition(property.getElementName());
if (attrDef == null) {
throw new IllegalStateException("No definition for attribute " + property);
}
@SuppressWarnings("rawtypes") ResourceAttribute primaryIdentifier = attrDef.instantiate();
primaryIdentifier.setRealValue(property.getRealValue());
primaryIdentifiers.add(primaryIdentifier);
}
}
LOGGER.trace("Resolved {} to primary identifiers {} (object class {})", identification, primaryIdentifiers, objDef);
return new ResourceObjectIdentification(identification.getResourceObjectDefinition(), primaryIdentifiers, identification.getSecondaryIdentifiers());
}
use of com.evolveum.midpoint.schema.processor.ResourceObjectDefinition in project midpoint by Evolveum.
the class ResourceObjectReferenceResolver method fetchResourceObject.
PrismObject<ShadowType> fetchResourceObject(ProvisioningContext ctx, Collection<? extends ResourceAttribute<?>> identifiers, AttributesToReturn attributesToReturn, @Nullable PrismObject<ShadowType> repoShadow, OperationResult parentResult) throws ObjectNotFoundException, CommunicationException, SchemaException, SecurityViolationException, ConfigurationException, ExpressionEvaluationException {
ConnectorInstance connector = ctx.getConnector(ReadCapabilityType.class, parentResult);
ResourceObjectDefinition objectDefinition = ctx.getObjectDefinitionRequired();
try {
ReadCapabilityType readCapability = ctx.getEffectiveCapability(ReadCapabilityType.class);
if (readCapability == null) {
throw new UnsupportedOperationException("Resource does not support 'read' operation: " + ctx.toHumanReadableDescription());
}
if (Boolean.TRUE.equals(readCapability.isCachingOnly())) {
return repoShadow;
}
ResourceObjectIdentification identification = ResourceObjectIdentification.create(objectDefinition, identifiers);
ResourceObjectIdentification resolvedIdentification = resolvePrimaryIdentifiers(ctx, identification, parentResult);
resolvedIdentification.validatePrimaryIdentifiers();
return connector.fetchObject(resolvedIdentification, attributesToReturn, ctx.getUcfExecutionContext(), parentResult);
} catch (ObjectNotFoundException e) {
// Not finishing the result because we did not create it! (The same for other catch clauses.)
parentResult.recordFatalErrorNotFinish("Object not found. Identifiers: " + identifiers + ". Reason: " + e.getMessage(), e);
throw new ObjectNotFoundException("Object not found. identifiers=" + identifiers + ", objectclass=" + PrettyPrinter.prettyPrint(objectDefinition.getTypeName()) + ": " + e.getMessage(), e, repoShadow != null ? repoShadow.getOid() : null);
} catch (CommunicationException e) {
parentResult.recordFatalErrorNotFinish("Error communication with the connector " + connector + ": " + e.getMessage(), e);
throw e;
} catch (GenericFrameworkException e) {
parentResult.recordFatalErrorNotFinish("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.recordFatalErrorNotFinish("Can't get resource object, schema error: " + ex.getMessage(), ex);
throw ex;
} catch (ExpressionEvaluationException ex) {
parentResult.recordFatalErrorNotFinish("Can't get resource object, expression error: " + ex.getMessage(), ex);
throw ex;
} catch (ConfigurationException e) {
parentResult.recordFatalErrorNotFinish(e);
throw e;
}
}
Aggregations