Skip to content

Commit

Permalink
Reduce intent guessing
Browse files Browse the repository at this point in the history
The goal is to reduce working with undefined (null) intents as much
as possible; and clarify the meaning of `defaultForKind`
and `defaultForObjectClass` flags in object type definition.

1. Cleaned up, organized, and documented definition of lookup methods
in ResourceSchema and ResourceSchemaUtil. The ones in ResourceSchema
are preferred. (The latter ones may be removed/changed in the future.)
The class ResourceObjectDefinitionResolver that originally contained
some of these methods is now hidden (package-private).

2. Universal (and too fuzzy) ResourceShadowDiscriminator was replaced
by more specialized classes, each of which has different fields,
invariants, and algorithms for use (e.g. matching proj. contexts):

 - ResourceShadowCoordinates (this has existed before),
 - ResourceOperationCoordinates,
 - ProjectionContextKey,
 - ProjectionContextFilter,
 - ConstructionTargetKey.

3. Schema change: removed default values for kind and intent from
ShadowDiscriminatorType.

4. Lens: There are many changes at places where projection contexts
are looked for. Originally all lookups were done by RSD, now it's more
diverse (situation-specific).

5. The management of LensProjectionContext#key (originally called
resourceShadowDiscriminator) has been reworked. Now it's determined
more eagerly than before. Also, all shadows that enter the clockwork
(in ways other than via SynchronizationServiceImpl or by client as full
objects) are now tried to be classified.
See ProjectionContextKeyFactory#createKey.

6. "Partially classified" contexts, i.e. those that contain known
kind but unknown intent, are no longer supported. The type
identification is either complete (kind+intent) or none at all
(objectClass only, or even not that).

7. ContextLoader/ProjectionLoadOperation were heavily refactored.
These changes were necessary to adapt to changed keying of projection
contexts. Also, some layering was introduced in the projection loading:
see LinkLevelOperation and ShadowLevelOperation inner classes.

8. DependencyProcessor was heavily refactored. The reason is that the
projection lookup mechanisms have been changed.

9. ProvisioningService#getObject now classifies shadows fetched, just
like methods for searching or live sync/async update do. This resolves
MID-7910.

10. Added missing "no fetch" option when updating projection contexts
from sync deltas. This was omitted by mistake somewhere around 4.4.

...plus other smaller code rearrangements, improvements and fixes.

Incompatible changes:

1. All new shadows that are explicitly created or linked ("by value"
i.e. not from repository) must be fully classified. The client
is responsible for providing both kind and intent values in them.

2. Dependency specification must contain the intent. (To be discussed.)

3. Methods in ProvisioningService have minor changes in parameter types
(ResourceShadowCoordinates -> ResourceOperationCoordinates).

4. ContextLoader is now in "...model.impl.lens.projector.loader"
package (relevant for logging config & trace analysis).

Unrelated changes:

- Trying to reduce the size of traces when embedded clockwork
(typically because of the discovery) is executed. The problem is that
the shadow contains the whole processing in the fetchResult. So,
OperationResult#createBeanReduced was created, as well as some reduction
in shadow cloning during saving of the trace is now done.
  • Loading branch information
mederly committed Jun 8, 2022
1 parent 57f24b3 commit d62cd32
Show file tree
Hide file tree
Showing 298 changed files with 6,485 additions and 4,830 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
*/
package com.evolveum.midpoint.gui.api.factory.wrapper;

import com.evolveum.midpoint.schema.ResourceShadowCoordinates;
import com.evolveum.midpoint.schema.processor.ResourceAssociationDefinition;
import com.evolveum.midpoint.gui.api.prism.ItemStatus;
import com.evolveum.midpoint.model.api.MetadataItemProcessingSpec;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.schema.ResourceShadowDiscriminator;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.util.annotation.Experimental;
Expand Down Expand Up @@ -43,7 +43,7 @@ public class WrapperContext {

//Shadow related attributes
private ResourceType resource;
private ResourceShadowDiscriminator discriminator;
private ResourceShadowCoordinates coordinates;

//Association related attributes
private Collection<ResourceAssociationDefinition> resourceAssociationDefinitions;
Expand Down Expand Up @@ -108,8 +108,8 @@ public ResourceType getResource() {
return resource;
}

public ResourceShadowDiscriminator getDiscriminator() {
return discriminator;
public ResourceShadowCoordinates getCoordinates() {
return coordinates;
}

public void setResource(ResourceType resource) {
Expand All @@ -124,8 +124,8 @@ public void setRefinedAssociationDefinitions(Collection<ResourceAssociationDefin
this.resourceAssociationDefinitions = resourceAssociationDefinitions;
}

public void setDiscriminator(ResourceShadowDiscriminator discriminator) {
this.discriminator = discriminator;
public void setCoordinates(ResourceShadowCoordinates coordinates) {
this.coordinates = coordinates;
}

public boolean isShowEmpty() {
Expand Down Expand Up @@ -253,7 +253,7 @@ public WrapperContext clone() {
ctx.setShowEmpty(showEmpty);
ctx.setObjectStatus(objectStatus);
ctx.setResource(resource);
ctx.setDiscriminator(discriminator);
ctx.setCoordinates(coordinates);
ctx.setCreateOperational(createOperational);
ctx.setVirtualItemSpecification(virtualItemSpecification);
ctx.setObject(object);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -446,8 +446,8 @@ public static ObjectFilter getShadowTypeFilterForAssociation(ConstructionType co

ObjectQuery query = prismContext.queryFactory().createQuery();
try {
ResourceSchema refinedResourceSchema = ResourceSchemaFactory.getCompleteSchema(resource);
ResourceObjectDefinition oc = refinedResourceSchema.findObjectDefinition(construction.getKind(), construction.getIntent());
ResourceSchema schema = ResourceSchemaFactory.getCompleteSchema(resource);
ResourceObjectDefinition oc = schema.findDefinitionForConstruction(construction);
if (oc == null) {
return null;
}
Expand Down Expand Up @@ -2977,7 +2977,7 @@ public static ItemVisibility checkShadowActivationAndPasswordVisibility(ItemWrap

try {
ResourceSchema resourceSchema = ResourceSchemaFactory.getCompleteSchema(resource);
ocd = ResourceObjectDefinitionResolver.getDefinitionForShadow(resourceSchema, shadowType);
ocd = resourceSchema.findDefinitionForShadow(shadowType);
} catch (SchemaException | ConfigurationException e) {
LOGGER.error("Cannot find refined definition for {} in {}", shadowType, resource);
}
Expand Down Expand Up @@ -3078,7 +3078,7 @@ public static boolean isAssociationSupported(ShadowType shadowType, IModel<Resou

try {
ResourceSchema resourceSchema = ResourceSchemaFactory.getCompleteSchema(resource.asPrismObject());
ocd = ResourceObjectDefinitionResolver.getDefinitionForShadow(resourceSchema, shadowType);
ocd = resourceSchema.findDefinitionForShadow(shadowType);
} catch (SchemaException | ConfigurationException e) {
LOGGER.error("Cannot find refined definition for {} in {}", shadowType, resource);
}
Expand Down Expand Up @@ -3752,8 +3752,8 @@ public static String getAssociationDisplayName(ResourceAssociationDefinition ass
if (assocDef.getDisplayName() != null) {
sb.append(assocDef.getDisplayName()).append(", ");
}
if (assocDef.getDefinitionBean() != null && assocDef.getDefinitionBean().getRef() != null) {
sb.append("ref: ").append(assocDef.getDefinitionBean().getRef().getItemPath().toString());
if (assocDef.getDefinitionBean().getRef() != null) {
sb.append("ref: ").append(assocDef.getDefinitionBean().getRef().getItemPath());
}
return sb.toString();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ private IModel<String> getKindIntentLabelModelForDisplayNamePanel(PrismContainer
OperationResult result = task.getResult();
PrismObject<ResourceType> resource = WebModelServiceUtils.loadObject(ResourceType.class, ((ConstructionValueWrapper) constructionValue).getResourceOid(), getPageBase(), task, result);
kind = ((ConstructionValueWrapper) constructionValue).getKind();
intent = ((ConstructionValueWrapper) constructionValue).getIntent(resource);
intent = ((ConstructionValueWrapper) constructionValue).determineIntent(resource);
} else {
kind = assignment.getConstruction().getKind();
intent = assignment.getConstruction().getIntent();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import com.evolveum.midpoint.prism.util.PrismUtil;
import com.evolveum.midpoint.prism.xml.XmlTypeConverter;
import com.evolveum.midpoint.schema.ResourceShadowCoordinates;
import com.evolveum.midpoint.web.component.search.*;

import org.apache.commons.collections4.CollectionUtils;
Expand All @@ -33,7 +34,6 @@
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.prism.path.ItemPathCollectionsUtil;
import com.evolveum.midpoint.prism.schema.SchemaRegistry;
import com.evolveum.midpoint.schema.ResourceShadowDiscriminator;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.schema.util.FullTextSearchUtil;
import com.evolveum.midpoint.task.api.Task;
Expand Down Expand Up @@ -370,12 +370,12 @@ public static <C extends Containerable> Search<ShadowType> createProjectionsTabS
}

private static <C extends Containerable> Search<C> createSearch(
SearchConfigurationWrapper<C> searchConfigurationWrapper, ResourceShadowDiscriminator discriminator,
SearchConfigurationWrapper<C> searchConfigurationWrapper, ResourceShadowCoordinates coordinates,
ModelServiceLocator modelServiceLocator, Search.PanelType panelType, boolean mergeWithDefaultSearchWrapper) {
SearchConfigurationWrapper<C> searchConfWrapper;
if (mergeWithDefaultSearchWrapper) {
SearchConfigurationWrapper<C> defaultWrapper = createDefaultSearchBoxConfigurationWrapper(searchConfigurationWrapper.getTypeClass(),
discriminator, modelServiceLocator);
SearchConfigurationWrapper<C> defaultWrapper = createDefaultSearchBoxConfigurationWrapper(
searchConfigurationWrapper.getTypeClass(), coordinates, modelServiceLocator);
searchConfWrapper = combineSearchBoxConfiguration(defaultWrapper, searchConfigurationWrapper);
} else {
searchConfWrapper = searchConfigurationWrapper;
Expand Down Expand Up @@ -417,13 +417,13 @@ private static <C extends Containerable> Search<C> createSearch(
}

public static <C extends Containerable> PropertySearchItemWrapper createPropertySearchItemWrapper(Class<C> type,
SearchItemType item, ResourceShadowDiscriminator discriminator, ModelServiceLocator modelServiceLocator) {
SearchItemType item, ResourceShadowCoordinates coordinates, ModelServiceLocator modelServiceLocator) {
if (item.getPath() == null) {
return null;
}
PrismContainerDefinition<C> def = null;
PrismContainerDefinition<C> def;
if (ObjectType.class.isAssignableFrom(type) && modelServiceLocator != null) {
def = findObjectDefinition((Class<? extends ObjectType>) type, discriminator, modelServiceLocator);
def = findObjectDefinition((Class<? extends ObjectType>) type, coordinates, modelServiceLocator);
} else {
def = PrismContext.get().getSchemaRegistry().findContainerDefinitionByCompileTimeClass(type);
}
Expand Down Expand Up @@ -744,12 +744,12 @@ public static <C extends Containerable> SearchConfigurationWrapper<C> createDefa
return createDefaultSearchBoxConfigurationWrapper(type, null, modelServiceLocator);
}

public static <C extends Containerable> SearchConfigurationWrapper<C> createDefaultSearchBoxConfigurationWrapper(Class<C> type,
ResourceShadowDiscriminator discriminator, ModelServiceLocator modelServiceLocator) {
public static <C extends Containerable> SearchConfigurationWrapper<C> createDefaultSearchBoxConfigurationWrapper(
Class<C> type, ResourceShadowCoordinates coordinates, ModelServiceLocator modelServiceLocator) {
SearchConfigurationWrapper searchConfigWrapper = new SearchConfigurationWrapper(type);
PrismContainerDefinition<C> def = null;
if (ObjectType.class.isAssignableFrom(type)) {
def = findObjectDefinition((Class<? extends ObjectType>) type, discriminator, modelServiceLocator);
def = findObjectDefinition((Class<? extends ObjectType>) type, coordinates, modelServiceLocator);
} else {
def = PrismContext.get().getSchemaRegistry().findContainerDefinitionByCompileTimeClass(type);
}
Expand All @@ -776,7 +776,7 @@ public static <C extends Containerable> SearchConfigurationWrapper<C> createDefa
}

public static <T extends ObjectType> PrismObjectDefinition findObjectDefinition(
Class<T> type, ResourceShadowDiscriminator discriminator,
Class<T> type, ResourceShadowCoordinates coordinates,
ModelServiceLocator modelServiceLocator) {

Task task = modelServiceLocator.createSimpleTask(LOAD_OBJECT_DEFINITION);
Expand All @@ -789,8 +789,8 @@ public static <T extends ObjectType> PrismObjectDefinition findObjectDefinition(
PrismObject empty = modelServiceLocator.getPrismContext().createObject(type);

if (ShadowType.class.equals(type)) {
return modelServiceLocator.getModelInteractionService().getEditShadowDefinition(discriminator,
AuthorizationPhaseType.REQUEST, task, result);
return modelServiceLocator.getModelInteractionService().getEditShadowDefinition(
coordinates, AuthorizationPhaseType.REQUEST, task, result);
} else {
return modelServiceLocator.getModelInteractionService().getEditObjectDefinition(
empty, AuthorizationPhaseType.REQUEST, task, result);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,7 @@ private List<ItemName> getChoicesList(PrismPropertyPanelContext<ItemPathType> ct
PrismObject<ResourceType> resource = WebModelServiceUtils.loadObject(ResourceType.class,
constructionWrapper.getResourceOid(), SelectorOptions.createCollection(GetOperationOptions.createNoFetch()),
ctx.getPageBase(), task, result);
ResourceSchema schema = constructionWrapper.getRefinedSchema(resource);
if (schema == null) {
return new ArrayList<>();
}
ResourceObjectDefinition rOcd =
schema.findObjectDefinition(constructionWrapper.getKind(), constructionWrapper.getIntent(resource));
ResourceObjectDefinition rOcd = constructionWrapper.getResourceObjectDefinition(resource);
if (rOcd == null) {
return Collections.emptyList();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import com.evolveum.midpoint.gui.api.component.BasePanel;
import com.evolveum.midpoint.gui.api.page.PageBase;
import com.evolveum.midpoint.model.api.context.ModelContext;
import com.evolveum.midpoint.schema.ResourceShadowDiscriminator;
import com.evolveum.midpoint.model.api.context.ProjectionContextKey;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.util.logging.Trace;
Expand Down Expand Up @@ -171,10 +171,12 @@ private Label createImageLabel(IModel<String> cssClass, IModel<String> title) {
private void populateStatusItem(ListItem<ProgressReportActivityDto> item) {
item.add(new Label(ID_ACTIVITY_DESCRIPTION, (IModel<String>) () -> {
ProgressReportActivityDto si = item.getModelObject();
if (si.getActivityType() == RESOURCE_OBJECT_OPERATION && si.getResourceShadowDiscriminator() != null) {
ResourceShadowDiscriminator rsd = si.getResourceShadowDiscriminator();
return createStringResource("ProgressPanel.populateStatusItem.resourceObjectActivity", createStringResource(rsd.getKind()).getString(),
rsd.getIntent(),si.getResourceName()).getString();
ProjectionContextKey key = si.getProjectionContextKey();
if (si.getActivityType() == RESOURCE_OBJECT_OPERATION && key != null) {
return createStringResource("ProgressPanel.populateStatusItem.resourceObjectActivity",
createStringResource(key.getKind()).getString(),
key.getIntent(),
si.getResourceName()).getString();
} else {
return createStringResource(si.getActivityType()).getString();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@
import java.util.stream.Collectors;
import javax.xml.namespace.QName;

import com.evolveum.midpoint.schema.ResourceShadowCoordinates;
import com.evolveum.midpoint.schema.processor.*;
import com.evolveum.midpoint.util.exception.ConfigurationException;

import com.evolveum.midpoint.gui.impl.component.search.SearchFactory;
import org.apache.commons.collections4.CollectionUtils;
import com.evolveum.midpoint.schema.processor.ResourceObjectTypeDefinition;
import com.evolveum.midpoint.schema.processor.ResourceSchema;
import com.evolveum.midpoint.schema.processor.ResourceSchemaFactory;

import com.evolveum.midpoint.web.component.dialog.DeleteConfirmationPanel;

import com.evolveum.midpoint.gui.impl.component.search.AbstractSearchItemWrapper;
Expand Down Expand Up @@ -68,7 +68,6 @@
import com.evolveum.midpoint.prism.*;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.schema.GetOperationOptions;
import com.evolveum.midpoint.schema.ResourceShadowDiscriminator;
import com.evolveum.midpoint.schema.SelectorOptions;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.result.OperationResult;
Expand Down Expand Up @@ -489,11 +488,11 @@ private ContainerPanelConfigurationType getBasicShadowPanelConfiguration(ShadowT
}

private GuiShadowDetailsPageType findShadowDetailsPageConfiguration(ShadowType shadowType) {
return getPageBase().getCompiledGuiProfile().findShadowDetailsConfiguration(createResourceShadowDiscriminator(shadowType));
return getPageBase().getCompiledGuiProfile().findShadowDetailsConfiguration(createResourceShadowCoordinates(shadowType));
}

private ResourceShadowDiscriminator createResourceShadowDiscriminator(ShadowType shadow) {
return new ResourceShadowDiscriminator(shadow.getResourceRef().getOid(), shadow.getKind(), shadow.getIntent(), null, false);
private ResourceShadowCoordinates createResourceShadowCoordinates(ShadowType shadow) {
return new ResourceShadowCoordinates(shadow.getResourceRef().getOid(), shadow.getKind(), shadow.getIntent(), null);
}

private IModel<ShadowWrapper> getParentModel(IModel<PrismContainerValueWrapper<ShadowType>> model) {
Expand Down Expand Up @@ -594,9 +593,7 @@ private void addSelectedAccountPerformed(AjaxRequestTarget target, List<Resource
LOGGER.trace("Refined schema for {}\n{}", resource, refinedSchema.debugDump());
}

// TODO are we OK with "any" account definition?
ResourceObjectTypeDefinition accountDefinition = refinedSchema
.findDefaultOrAnyObjectTypeDefinition(ShadowKindType.ACCOUNT);
ResourceObjectDefinition accountDefinition = refinedSchema.findDefaultDefinitionForKind(ShadowKindType.ACCOUNT);
if (accountDefinition == null) {
error(getString("pageAdminFocus.message.couldntCreateAccountNoAccountSchema",
resource.getName()));
Expand All @@ -618,13 +615,21 @@ private void addSelectedAccountPerformed(AjaxRequestTarget target, List<Resource
target.add(getMultivalueContainerListPanel());
}

private ShadowType createNewShadow(ResourceType resource, ResourceObjectTypeDefinition accountDefinition) {
ShadowType shadow = new ShadowType(getPrismContext());
private ShadowType createNewShadow(ResourceType resource, ResourceObjectDefinition accountDefinition) {
ShadowType shadow = new ShadowType();
shadow.setResourceRef(ObjectTypeUtil.createObjectRef(resource, SchemaConstants.ORG_DEFAULT));
QName objectClass = accountDefinition.getTypeName();
shadow.setObjectClass(objectClass);
shadow.setIntent(accountDefinition.getIntent());
shadow.setKind(accountDefinition.getKind());
ResourceObjectTypeIdentification typeId = accountDefinition.getTypeIdentification();
if (typeId != null) {
shadow.setKind(typeId.getKind());
shadow.setIntent(typeId.getIntent());
} else if (accountDefinition.getObjectClassDefinition().isDefaultAccountDefinition()) {
shadow.setKind(ShadowKindType.ACCOUNT);
shadow.setIntent(SchemaConstants.INTENT_DEFAULT);
} else {
throw new IllegalStateException("No suitable account definition could be found");
}
return shadow;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@
*/
package com.evolveum.midpoint.gui.impl.page.admin.resource;

import com.evolveum.midpoint.gui.api.model.LoadableModel;
import com.evolveum.midpoint.gui.api.util.ModelServiceLocator;
import com.evolveum.midpoint.gui.impl.page.admin.ObjectDetailsModels;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.schema.ResourceShadowDiscriminator;
import com.evolveum.midpoint.schema.ResourceShadowCoordinates;
import com.evolveum.midpoint.xml.ns._public.common.common_3.GuiObjectDetailsPageType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType;

Expand All @@ -23,11 +22,11 @@ public ShadowDetailsModel(LoadableDetachableModel<PrismObject<ShadowType>> prism
}

protected GuiObjectDetailsPageType loadDetailsPageConfiguration(PrismObject<ShadowType> prismObject) {
return getModelServiceLocator().getCompiledGuiProfile().findShadowDetailsConfiguration(createResourceShadowDiscriminator(getPrismObject().asObjectable()));
return getModelServiceLocator().getCompiledGuiProfile().findShadowDetailsConfiguration(createResourceShadowCoordinates(getPrismObject().asObjectable()));
}

private ResourceShadowDiscriminator createResourceShadowDiscriminator(ShadowType shadow) {
return new ResourceShadowDiscriminator(shadow.getResourceRef().getOid(), shadow.getKind(), shadow.getIntent(), null, false);
private ResourceShadowCoordinates createResourceShadowCoordinates(ShadowType shadow) {
return new ResourceShadowCoordinates(shadow.getResourceRef().getOid(), shadow.getKind(), shadow.getIntent());
}

}

0 comments on commit d62cd32

Please sign in to comment.