Skip to content

Commit

Permalink
Migrate multi-propagation task to activities
Browse files Browse the repository at this point in the history
(Not tested yet, though.)
  • Loading branch information
mederly committed Jun 16, 2021
1 parent 1f75bc2 commit f93d56f
Show file tree
Hide file tree
Showing 10 changed files with 323 additions and 217 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright (C) 2010-2021 Evolveum and contributors
*
* This work is dual-licensed under the Apache License 2.0
* and European Union Public License. See LICENSE file for details.
*/

package com.evolveum.midpoint.schema.util.task.work;

import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.util.exception.SystemException;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectSetType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;
import com.evolveum.prism.xml.ns._public.query_3.QueryType;

import org.jetbrains.annotations.NotNull;

import javax.xml.namespace.QName;

public class ObjectSetUtil {

public static ObjectSetType setFromRef(ObjectReferenceType ref, QName defaultTypeName) {
if (ref == null) {
return new ObjectSetType(PrismContext.get())
.objectType(defaultTypeName);
} else if (ref.getOid() != null) {
return new ObjectSetType(PrismContext.get())
.objectType(getTypeName(ref, defaultTypeName))
.objectQuery(createOidQuery(ref.getOid()));
} else {
return new ObjectSetType(PrismContext.get())
.objectType(getTypeName(ref, defaultTypeName))
.objectQuery(new QueryType()
.filter(ref.getFilter()));
}
}

private static QueryType createOidQuery(@NotNull String oid) {
try {
return PrismContext.get().getQueryConverter().createQueryType(
PrismContext.get().queryFor(ObjectType.class)
.id(oid)
.build());
} catch (SchemaException e) {
throw new SystemException(e);
}
}

private static QName getTypeName(ObjectReferenceType ref, QName defaultTypeName) {
return ref.getType() != null ? ref.getType() : defaultTypeName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5469,47 +5469,43 @@
<a:since>4.4</a:since>
</xsd:appinfo>
</xsd:annotation>
<xsd:complexContent>
<xsd:extension base="tns:AbstractWorkDefinitionType">
<xsd:sequence>
<xsd:element name="objectType" type="xsd:QName" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
TODO
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="objectQuery" type="q:QueryType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
TODO
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="searchOptions" type="c:SelectorQualifiedGetOptionsType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
TODO
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="useRepositoryDirectly" type="xsd:boolean" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Whether to use repository directly when searching for objects.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="iterationMethod" type="c:IterationMethodType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
How to iterate through objects. Should be used only when really needed.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
<xsd:sequence>
<xsd:element name="objectType" type="xsd:QName" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
TODO
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="objectQuery" type="q:QueryType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
TODO
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="searchOptions" type="c:SelectorQualifiedGetOptionsType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
TODO
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="useRepositoryDirectly" type="xsd:boolean" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Whether to use repository directly when searching for objects.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="iterationMethod" type="c:IterationMethodType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
How to iterate through objects. Should be used only when really needed.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="objectSet" type="tns:ObjectSetType"/>

Expand All @@ -5527,7 +5523,7 @@
<xsd:complexContent>
<xsd:extension base="tns:AbstractWorkDefinitionType">
<xsd:sequence>
<xsd:element name="objectSet" type="tns:ObjectSetType" minOccurs="0"/>
<xsd:element name="objects" type="tns:ObjectSetType" minOccurs="0"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
Expand Down Expand Up @@ -5696,7 +5692,7 @@
</xsd:sequence>
<xsd:attribute name="id" type="xsd:long"/>
</xsd:complexType>
<xsd:element name="abstractWorKDefinition" type="tns:AbstractWorkDefinitionType" />
<xsd:element name="abstractWorkDefinition" type="tns:AbstractWorkDefinitionType" />

<xsd:complexType name="ResourceBasedWorkDefinitionType">
<xsd:annotation>
Expand Down Expand Up @@ -5741,11 +5737,35 @@
</xsd:annotation>
<xsd:complexContent>
<xsd:extension base="tns:ResourceBasedWorkDefinitionType">
<!--<xsd:sequence>-->
<!-- <xsd:element name="shadows" type="tns:ObjectSetType" minOccurs="0"/>-->
<!--</xsd:sequence>-->
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="propagationWorkDefinition" type="tns:PropagationWorkDefinitionType"/>

<xsd:complexType name="MultiPropagationWorkDefinitionType">
<xsd:annotation>
<xsd:documentation>
TODO
</xsd:documentation>
<xsd:appinfo>
<a:experimental>true</a:experimental>
<a:container>true</a:container>
<a:since>4.4</a:since>
</xsd:appinfo>
</xsd:annotation>
<xsd:complexContent>
<xsd:extension base="tns:AbstractWorkDefinitionType">
<xsd:sequence>
<xsd:element name="resources" type="tns:ObjectSetType" minOccurs="0"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="multiPropagationWorkDefinition" type="tns:MultiPropagationWorkDefinitionType"/>

<xsd:complexType name="ActivityPathType">
<xsd:annotation>
<xsd:documentation>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,93 @@
package com.evolveum.midpoint.provisioning.impl.shadows.task;

import com.evolveum.midpoint.repo.common.task.*;
import com.evolveum.midpoint.task.api.RunningTask;
import com.evolveum.midpoint.task.api.Task;

import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;

import org.jetbrains.annotations.NotNull;

import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.crypto.EncryptionException;
import com.evolveum.midpoint.prism.query.ObjectQuery;
import com.evolveum.midpoint.provisioning.ucf.api.GenericFrameworkException;
import com.evolveum.midpoint.repo.common.activity.execution.ExecutionInstantiationContext;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.util.exception.CommonException;
import com.evolveum.midpoint.util.exception.SystemException;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AbstractActivityWorkStateType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType;

/**
* Execution of a multi-propagation task.
* Execution of a propagation task. It has always a single part, so the resource can be stored here.
*/
@ItemProcessorClass(MultiPropagationItemProcessor.class)
@HandledObjectType(ResourceType.class)
public class MultiPropagationActivityExecution
extends AbstractSearchIterativeActivityExecutionOld
extends AbstractSearchIterativeActivityExecution
<ResourceType,
MultiPropagationTaskHandler,
MultiPropagationTaskHandler.TaskExecution,
MultiPropagationActivityExecution,
MultiPropagationItemProcessor> {
MultiPropagationWorkDefinition,
MultiPropagationActivityHandler,
MultiPropagationActivityExecution,
AbstractActivityWorkStateType> {

private static final Trace LOGGER = TraceManager.getTrace(MultiPropagationActivityExecution.class);

private static final String SHORT_NAME = "Multi-propagation";

MultiPropagationActivityExecution(
@NotNull ExecutionInstantiationContext<MultiPropagationWorkDefinition, MultiPropagationActivityHandler> context) {
super(context, SHORT_NAME);
}

@Override
public @NotNull ActivityReportingOptions getDefaultReportingOptions() {
ActivityReportingOptions options = new ActivityReportingOptions();
options.setPreserveStatistics(false);
options.setEnableSynchronizationStatistics(false);
options.setSkipWritingOperationExecutionRecords(true); // to avoid resource change (invalidates the caches)
return options;
}

@Override
protected @NotNull ItemProcessor<PrismObject<ResourceType>> createItemProcessor(OperationResult opResult) {
return createDefaultItemProcessor(this::propagateOperationsOnResource);
}

private boolean propagateOperationsOnResource(PrismObject<ResourceType> resource,
ItemProcessingRequest<PrismObject<ResourceType>> request, RunningTask workerTask, OperationResult taskResult)
throws SchemaException {

LOGGER.trace("Propagating provisioning operations on {}", resource);

ObjectQuery shadowQuery = beans.prismContext.queryFor(ShadowType.class)
.item(ShadowType.F_RESOURCE_REF).ref(resource.getOid())
.and()
.exists(ShadowType.F_PENDING_OPERATION)
.build();

beans.repositoryService.searchObjectsIterative(ShadowType.class, shadowQuery, (shadow, result) -> {
propagateOperationsOnShadow(shadow, resource, workerTask, result);
return true;
}, null, true, taskResult);

LOGGER.trace("Propagation of {} done", resource);
return true;
}

private void propagateOperationsOnShadow(PrismObject<ShadowType> shadow, PrismObject<ResourceType> resource,
Task workerTask, OperationResult result) {
try {
getActivityHandler().shadowsFacade.propagateOperations(resource, shadow, workerTask, result);
} catch (CommonException | GenericFrameworkException | EncryptionException e) {
throw new SystemException("Provisioning error: " + e.getMessage(), e);
}
}

public MultiPropagationActivityExecution(MultiPropagationTaskHandler.TaskExecution taskExecution) {
super(taskExecution);
@Override
protected void debugDumpExtra(StringBuilder sb, int indent) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright (C) 2010-2021 Evolveum and contributors
*
* This work is dual-licensed under the Apache License 2.0
* and European Union Public License. See LICENSE file for details.
*/
package com.evolveum.midpoint.provisioning.impl.shadows.task;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.xml.namespace.QName;

import com.evolveum.midpoint.xml.ns._public.common.common_3.*;

import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.evolveum.midpoint.provisioning.api.ProvisioningService;
import com.evolveum.midpoint.provisioning.impl.shadows.ShadowsFacade;
import com.evolveum.midpoint.repo.common.activity.definition.WorkDefinitionFactory;
import com.evolveum.midpoint.repo.common.activity.execution.ExecutionInstantiationContext;
import com.evolveum.midpoint.repo.common.activity.handlers.ActivityHandler;
import com.evolveum.midpoint.repo.common.activity.handlers.ActivityHandlerRegistry;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.result.OperationResult;

/**
* TODO
*/
@Component
public class MultiPropagationActivityHandler implements ActivityHandler<MultiPropagationWorkDefinition, MultiPropagationActivityHandler> {

public static final String LEGACY_HANDLER_URI = SchemaConstants.NS_PROVISIONING_TASK + "/propagation/multi-handler-3";
private static final String ARCHETYPE_OID = SystemObjectsType.ARCHETYPE_SYSTEM_TASK.value(); // TODO

@Autowired WorkDefinitionFactory workDefinitionFactory;
@Autowired ActivityHandlerRegistry handlerRegistry;
@Autowired ProvisioningService provisioningService;
@Autowired ShadowsFacade shadowsFacade;

@PostConstruct
public void register() {
handlerRegistry.register(MultiPropagationWorkDefinitionType.COMPLEX_TYPE, LEGACY_HANDLER_URI,
MultiPropagationWorkDefinition.class, MultiPropagationWorkDefinition::new, this);
}

@PreDestroy
public void unregister() {
handlerRegistry.unregister(MultiPropagationWorkDefinitionType.COMPLEX_TYPE, LEGACY_HANDLER_URI,
MultiPropagationWorkDefinition.class);
}

@Override
public @NotNull MultiPropagationActivityExecution createExecution(
@NotNull ExecutionInstantiationContext<MultiPropagationWorkDefinition, MultiPropagationActivityHandler> context,
@NotNull OperationResult result) {
return new MultiPropagationActivityExecution(context);
}

@Override
public String getIdentifierPrefix() {
return "multi-propagation";
}

@Override
public @NotNull QName getWorkStateTypeName() {
return AbstractActivityWorkStateType.COMPLEX_TYPE;
}
}

0 comments on commit f93d56f

Please sign in to comment.