Skip to content

Commit

Permalink
Skipping reading associations in PageContentAccounts. Fixed bug with …
Browse files Browse the repository at this point in the history
…multiple subjectToObject associations.
  • Loading branch information
mederly committed Oct 21, 2014
1 parent 5e4fd57 commit e0f4489
Show file tree
Hide file tree
Showing 10 changed files with 286 additions and 60 deletions.
Expand Up @@ -480,7 +480,7 @@ private LoadableModel<Integer> createTotalsModel(final SynchronizationSituationT
@Override
protected Integer load() {
// ObjectFilter resourceFilter = createResourceQueryFilter();
ObjectFilter resourceFilter = createObjectQuery().getFilter();
ObjectFilter resourceFilter = createObjectQuery().getFilter(); // leads to invalid filters [e.g. AND(something,null)]

if (resourceFilter == null) {
return 0;
Expand Down
Expand Up @@ -21,6 +21,9 @@
import com.evolveum.midpoint.prism.query.ObjectFilter;
import com.evolveum.midpoint.prism.query.ObjectPaging;
import com.evolveum.midpoint.prism.query.ObjectQuery;
import com.evolveum.midpoint.schema.GetOperationOptions;
import com.evolveum.midpoint.schema.RetrieveOption;
import com.evolveum.midpoint.schema.SelectorOptions;
import com.evolveum.midpoint.schema.processor.ResourceAttribute;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.schema.util.ObjectQueryUtil;
Expand Down Expand Up @@ -102,7 +105,9 @@ public Iterator<AccountContentDto> internalIterator(long first, long count) {
LOGGER.trace("Query filter:\n{}", query);
}

List<PrismObject<ShadowType>> list = getModel().searchObjects(ShadowType.class, query, null, task, result);
Collection<SelectorOptions<GetOperationOptions>> options =
SelectorOptions.createCollection(ShadowType.F_ASSOCIATION, GetOperationOptions.createRetrieve(RetrieveOption.EXCLUDE));
List<PrismObject<ShadowType>> list = getModel().searchObjects(ShadowType.class, query, options, task, result);

AccountContentDto dto;
for (PrismObject<ShadowType> object : list) {
Expand Down
Expand Up @@ -157,15 +157,17 @@ public static boolean hasToLoadPath(ItemPath path, Collection<SelectorOptions<Ge
}

RetrieveOption retrieveOption = option.getOptions().getRetrieve();
if (new ItemPath(UserType.F_JPEG_PHOTO).equivalent(path)) {
//user photo is not retrieved by default
switch (retrieveOption) {
case INCLUDE:
return true;
case EXCLUDE:
case DEFAULT:
default:
return false;
for (ItemPath notByDefault : PATHS_NOT_RETURNED_BY_DEFAULT) {
if (notByDefault.equivalent(path)) {
//this one is not retrieved by default
switch (retrieveOption) {
case INCLUDE:
return true;
case EXCLUDE:
case DEFAULT:
default:
return false;
}
}
}

Expand Down
Expand Up @@ -223,4 +223,5 @@ public abstract class SchemaConstants {
public static final QName APIT_ITEM_LIST = new QName(SchemaConstants.NS_API_TYPES, "itemList");
public static final QName C_ASSIGNMENT = new QName(SchemaConstants.NS_C, "assignment");

public static final QName C_NAME = new QName(SchemaConstants.NS_C, "name");
}
Expand Up @@ -134,7 +134,7 @@ private <S extends ShadowType,T> void postProcessEntitlementSubjectToEntitlement
if (associationName == null) {
throw new SchemaException("No name in entitlement association "+assocDefType+" in "+resourceType);
}

QName assocAttrName = assocDefType.getResourceObjectAssociationType().getAssociationAttribute();
if (assocAttrName == null) {
throw new SchemaException("No association attribute defined in entitlement association '"+associationName+"' in "+resourceType);
Expand All @@ -148,25 +148,26 @@ private <S extends ShadowType,T> void postProcessEntitlementSubjectToEntitlement
// Nothing to do. No attribute to base the association on.
return;
}

QName valueAttrName = assocDefType.getResourceObjectAssociationType().getValueAttribute();
if (valueAttrName == null) {
throw new SchemaException("No value attribute defined in entitlement association '"+associationName+"' in "+resourceType);
}
RefinedAttributeDefinition valueAttrDef = entitlementDef.findAttributeDefinition(valueAttrName);
ResourceAttribute<T> valueAttribute = valueAttrDef.instantiate();

for (PrismPropertyValue<T> assocAttrPVal: assocAttr.getValues()) {
valueAttribute.add(assocAttrPVal.clone());
}

PrismContainerValue<ShadowAssociationType> associationCVal = associationContainer.createNewValue();
associationCVal.asContainerable().setName(associationName);
ResourceAttributeContainer identifiersContainer = new ResourceAttributeContainer(
ShadowAssociationType.F_IDENTIFIERS, entitlementDef.toResourceAttributeContainerDefinition(), prismContext);
associationCVal.add(identifiersContainer);
identifiersContainer.add(valueAttribute);
}

for (PrismPropertyValue<T> assocAttrPVal : assocAttr.getValues()) {

ResourceAttribute<T> valueAttribute = valueAttrDef.instantiate();
valueAttribute.add(assocAttrPVal.clone());

PrismContainerValue<ShadowAssociationType> associationCVal = associationContainer.createNewValue();
associationCVal.asContainerable().setName(associationName);
ResourceAttributeContainer identifiersContainer = new ResourceAttributeContainer(
ShadowAssociationType.F_IDENTIFIERS, entitlementDef.toResourceAttributeContainerDefinition(), prismContext);
associationCVal.add(identifiersContainer);
identifiersContainer.add(valueAttribute);
}
}

private <S extends ShadowType,T> void postProcessEntitlementEntitlementToSubject(ConnectorInstance connector,
ResourceType resourceType, final PrismObject<S> resourceObject,
Expand Down
Expand Up @@ -34,7 +34,6 @@
import org.springframework.stereotype.Component;

import com.evolveum.midpoint.common.ResourceObjectPattern;
import com.evolveum.midpoint.common.refinery.RefinedAssociationDefinition;
import com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition;
import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition;
import com.evolveum.midpoint.common.refinery.RefinedResourceSchema;
Expand All @@ -44,7 +43,6 @@
import com.evolveum.midpoint.prism.PrismContainer;
import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.PrismObjectDefinition;
import com.evolveum.midpoint.prism.PrismProperty;
import com.evolveum.midpoint.prism.PrismPropertyValue;
import com.evolveum.midpoint.prism.delta.ContainerDelta;
Expand Down Expand Up @@ -78,7 +76,6 @@
import com.evolveum.midpoint.schema.util.ResourceTypeUtil;
import com.evolveum.midpoint.schema.util.SchemaDebugUtil;
import com.evolveum.midpoint.schema.util.ShadowUtil;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.util.Holder;
import com.evolveum.midpoint.util.MiscUtil;
import com.evolveum.midpoint.util.PrettyPrinter;
Expand All @@ -100,7 +97,6 @@
import com.evolveum.midpoint.xml.ns._public.common.common_3.ProvisioningOperationTypeType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowAssociationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowIdentifiersType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType;
import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.ActivationCapabilityType;
Expand Down Expand Up @@ -191,8 +187,17 @@ public PrismObject<ShadowType> locateResourceObject(ConnectorInstance connector,
}

final ResourceAttribute<?> finalSecondaryIdentifier = secondaryIdentifier;

ObjectFilter filter = EqualFilter.createEqual(new ItemPath(ShadowType.F_ATTRIBUTES, secondaryIdentifierDef.getName()), secondaryIdentifierDef, secondaryIdentifier.getValue());

List<PrismPropertyValue> secondaryIdentifierValues = (List) secondaryIdentifier.getValues();
PrismPropertyValue secondaryIdentifierValue;
if (secondaryIdentifierValues.size() > 1) {
throw new IllegalStateException("Secondary identifier has more than one value: " + secondaryIdentifier.getValues());
} else if (secondaryIdentifierValues.size() == 1) {
secondaryIdentifierValue = secondaryIdentifierValues.get(0);
} else {
secondaryIdentifierValue = null;
}
ObjectFilter filter = EqualFilter.createEqual(new ItemPath(ShadowType.F_ATTRIBUTES, secondaryIdentifierDef.getName()), secondaryIdentifierDef, secondaryIdentifierValue);
ObjectQuery query = ObjectQuery.createObjectQuery(filter);
// query.setFilter(filter);
final Holder<PrismObject<ShadowType>> shadowHolder = new Holder<PrismObject<ShadowType>>();
Expand All @@ -212,7 +217,7 @@ public boolean handle(PrismObject<ShadowType> shadow) {
throw new ObjectNotFoundException("No object found for secondary identifier "+secondaryIdentifier);
}
PrismObject<ShadowType> shadow = shadowHolder.getValue();
return postProcessResourceObjectRead(connector, resource, shadow, objectClassDefinition, parentResult);
return postProcessResourceObjectRead(connector, resource, shadow, objectClassDefinition, true, parentResult);
} catch (GenericFrameworkException e) {
throw new GenericConnectorException(e.getMessage(), e);
}
Expand Down Expand Up @@ -741,16 +746,17 @@ private void executeEntitlements(ConnectorInstance connector, ResourceType resou

public void searchResourceObjects(final ConnectorInstance connector,
final ResourceType resourceType, final RefinedObjectClassDefinition objectClassDef,
final ResultHandler<ShadowType> resultHandler, ObjectQuery query, final OperationResult parentResult) throws SchemaException,
final ResultHandler<ShadowType> resultHandler, ObjectQuery query, final boolean fetchAssociations,
final OperationResult parentResult) throws SchemaException,
CommunicationException, ObjectNotFoundException, ConfigurationException {

AttributesToReturn attributesToReturn = ProvisioningUtil.createAttributesToReturn(objectClassDef, resourceType);

ResultHandler<ShadowType> innerResultHandler = new ResultHandler<ShadowType>() {
@Override
public boolean handle(PrismObject<ShadowType> shadow) {
try {
shadow = postProcessResourceObjectRead(connector, resourceType, shadow, objectClassDef, parentResult);
shadow = postProcessResourceObjectRead(connector, resourceType, shadow, objectClassDef, fetchAssociations, parentResult);
} catch (SchemaException e) {
throw new TunnelException(e);
} catch (CommunicationException e) {
Expand Down Expand Up @@ -834,7 +840,7 @@ private PrismObject<ShadowType> fetchResourceObject(ConnectorInstance connector,

PrismObject<ShadowType> resourceObject = connector.fetchObject(ShadowType.class, objectClassDefinition, identifiers,
attributesToReturn, parentResult);
return postProcessResourceObjectRead(connector, resource, resourceObject, objectClassDefinition, parentResult);
return postProcessResourceObjectRead(connector, resource, resourceObject, objectClassDefinition, true, parentResult); // todo consider whether it is always necessary to fetch the entitlements
} catch (ObjectNotFoundException e) {
parentResult.recordFatalError(
"Object not found. Identifiers: " + identifiers + ". Reason: " + e.getMessage(), e);
Expand Down Expand Up @@ -1213,7 +1219,7 @@ public List<Change<ShadowType>> fetchChanges(ConnectorInstance connector, Resour
}
} else {
PrismObject<ShadowType> currentShadow = postProcessResourceObjectRead(connector, resource, change.getCurrentShadow(),
objectClass, parentResult);
objectClass, true, parentResult);
change.setCurrentShadow(currentShadow);
}
}
Expand All @@ -1227,7 +1233,8 @@ public List<Change<ShadowType>> fetchChanges(ConnectorInstance connector, Resour
* Process simulated activation, credentials and other properties that are added to the object by midPoint.
*/
private PrismObject<ShadowType> postProcessResourceObjectRead(ConnectorInstance connector, ResourceType resourceType,
PrismObject<ShadowType> resourceObject, RefinedObjectClassDefinition objectClassDefinition, OperationResult parentResult) throws SchemaException, CommunicationException, GenericFrameworkException {
PrismObject<ShadowType> resourceObject, RefinedObjectClassDefinition objectClassDefinition, boolean fetchAssociations,
OperationResult parentResult) throws SchemaException, CommunicationException, GenericFrameworkException {

ShadowType resourceObjectType = resourceObject.asObjectable();
setProtectedFlag(resourceType, objectClassDefinition, resourceObject);
Expand All @@ -1249,7 +1256,9 @@ private PrismObject<ShadowType> postProcessResourceObjectRead(ConnectorInstance
}

// Entitlements
entitlementConverter.postProcessEntitlementsRead(connector, resourceType, resourceObject, objectClassDefinition, parentResult);
if (fetchAssociations) {
entitlementConverter.postProcessEntitlementsRead(connector, resourceType, resourceObject, objectClassDefinition, parentResult);
}

return resourceObject;
}
Expand Down
Expand Up @@ -821,7 +821,7 @@ public boolean handle(PrismObject<ShadowType> resourceShadow) {
applyAttributesDefinition(repoShadow, resourceType);

forceRenameIfNeeded(resourceShadow.asObjectable(), repoShadow.asObjectable(), objectClassDef, parentResult);

resultShadow = completeShadow(connector, resourceShadow, repoShadow,
resourceType, objectClassDef, parentResult);

Expand Down Expand Up @@ -870,8 +870,11 @@ public boolean handle(PrismObject<ShadowType> resourceShadow) {
}

};

boolean fetchAssociations = SelectorOptions.hasToLoadPath(ShadowType.F_ASSOCIATION, options);

resouceObjectConverter.searchResourceObjects(connector, resourceType, objectClassDef, resultHandler, attributeQuery, parentResult);
resouceObjectConverter.searchResourceObjects(connector, resourceType, objectClassDef, resultHandler,
attributeQuery, fetchAssociations, parentResult);

}

Expand Down Expand Up @@ -1512,7 +1515,7 @@ private PrismObject<ShadowType> completeShadow(ConnectorInstance connector, Pris

PrismObject<ShadowType> resultShadow = repoShadow.clone();
boolean resultIsResourceShadowClone = false;
if (resultShadow == null) {
if (resultShadow == null) { // todo how could this happen (see above)? [mederly]
resultShadow = resourceShadow.clone();
resultIsResourceShadowClone = true;
}
Expand Down
Expand Up @@ -136,7 +136,11 @@ public abstract class AbstractDummyTest extends AbstractIntegrationTest {
protected static final String PRIVILEGE_PILLAGE_OID = "c0c010c0-d34d-b44f-f11d-3332eeff0000";
protected static final String PRIVILEGE_PILLAGE_NAME = "pillage";

protected static final String FILENAME_ACCOUNT_SCRIPT = TEST_DIR + "account-script.xml";
protected static final String PRIVILEGE_BARGAIN_FILENAME = TEST_DIR + "privilege-bargain.xml";
protected static final String PRIVILEGE_BARGAIN_OID = "c0c010c0-d34d-b44f-f11d-3332eeff0001";
protected static final String PRIVILEGE_BARGAIN_NAME = "bargain";

protected static final String FILENAME_ACCOUNT_SCRIPT = TEST_DIR + "account-script.xml";
protected static final String ACCOUNT_NEW_SCRIPT_OID = "c0c010c0-d34d-b44f-f11d-33322212abcd";
protected static final String FILENAME_ENABLE_ACCOUNT = TEST_DIR + "modify-will-enable.xml";
protected static final String FILENAME_DISABLE_ACCOUNT = TEST_DIR + "modify-will-disable.xml";
Expand Down

0 comments on commit e0f4489

Please sign in to comment.