Skip to content

Commit

Permalink
MID-1840 (ModelService.executeChanges now returning executed deltas) …
Browse files Browse the repository at this point in the history
…+ fixing infra/common test failures.
  • Loading branch information
mederly committed May 5, 2014
1 parent e048a27 commit 9d5ed81
Show file tree
Hide file tree
Showing 10 changed files with 119 additions and 31 deletions.
Expand Up @@ -134,11 +134,13 @@ public static <V extends PrismValue> List<JAXBElement<RawType>> serializeValueEl
return null;
}
XNodeProcessor xnodeProcessor = item.getPrismContext().getXnodeProcessor();
List<JAXBElement<RawType>> elements = new ArrayList<>(1);
XNode xnode = xnodeProcessor.serializeItem(item);
RawType rawType = new RawType(xnode);
JAXBElement<RawType> jaxbElement = new JAXBElement<RawType>(SchemaConstants.C_VALUE, RawType.class, rawType);
elements.add(jaxbElement);
List<JAXBElement<RawType>> elements = new ArrayList<>(item.size());
for (PrismValue value : item.getValues()) {
XNode xnode = xnodeProcessor.serializeItemValue(value);
RawType rawType = new RawType(xnode);
JAXBElement<RawType> jaxbElement = new JAXBElement<>(SchemaConstants.C_VALUE, RawType.class, rawType);
elements.add(jaxbElement);
}
return elements;
}

Expand Down
Expand Up @@ -21,6 +21,7 @@
import com.evolveum.midpoint.prism.PrismProperty;
import com.evolveum.midpoint.prism.PrismPropertyDefinition;
import com.evolveum.midpoint.prism.PrismValue;
import com.evolveum.midpoint.prism.util.JaxbTestUtil;
import com.evolveum.midpoint.prism.util.PrismTestUtil;
import com.evolveum.midpoint.schema.MidPointPrismContextFactory;
import com.evolveum.midpoint.schema.constants.MidPointConstants;
Expand All @@ -31,6 +32,7 @@
import com.evolveum.midpoint.util.PrettyPrinter;
import com.evolveum.midpoint.util.exception.SchemaException;

import com.evolveum.prism.xml.ns._public.types_3.RawType;
import org.testng.AssertJUnit;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.Test;
Expand All @@ -41,6 +43,8 @@
import java.util.Collection;
import java.util.List;

import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.namespace.QName;

import static org.testng.AssertJUnit.*;
Expand Down Expand Up @@ -91,13 +95,13 @@ public void testValueElementsRoundtripInt() throws Exception {
doRoundtrip(origProperty, propDef, prismContext);
}

private void doRoundtrip(PrismProperty<?> origProperty, ItemDefinition propDef, PrismContext prismContext) throws SchemaException {
private void doRoundtrip(PrismProperty<?> origProperty, ItemDefinition propDef, PrismContext prismContext) throws SchemaException, JAXBException {
// WHEN
List<?> valueElements = StaticExpressionUtil.serializeValueElements(origProperty, "here somewhere");
List<JAXBElement<RawType>> valueElements = StaticExpressionUtil.serializeValueElements(origProperty, "here somewhere");

for (Object element: valueElements) {
if (element instanceof Element) {
System.out.println(DOMUtil.serializeDOMToString((Element)element));
if (element instanceof JAXBElement) {
System.out.println(JaxbTestUtil.getInstance().marshalElementToString((JAXBElement) element));
} else {
AssertJUnit.fail("Unexpected element type "+element.getClass());
}
Expand Down
Expand Up @@ -42,8 +42,14 @@ public ObjectDeltaOperation(ObjectDelta<T> objectDelta) {
super();
this.objectDelta = objectDelta;
}

public ObjectDelta<T> getObjectDelta() {

public ObjectDeltaOperation(ObjectDelta<T> objectDelta, OperationResult executionResult) {
super();
this.objectDelta = objectDelta;
this.executionResult = executionResult;
}

public ObjectDelta<T> getObjectDelta() {
return objectDelta;
}

Expand Down
Expand Up @@ -430,5 +430,17 @@
<xsd:element name="delta" type="t:ObjectDeltaType" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>

<xsd:complexType name="ObjectDeltaOperationListType">
<xsd:annotation>
<xsd:documentation>
List of object delta operations (deltas + operation results).
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="deltaOperation" type="c:ObjectDeltaOperationType" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>

</xsd:schema>

Expand Up @@ -90,7 +90,7 @@
<xsd:element name="executeChangesResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="result" type="c:OperationResultType" />
<xsd:element name="deltaOperationList" type="apit:ObjectDeltaOperationListType" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
Expand Down
Expand Up @@ -29,6 +29,7 @@
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.ObjectDeltaOperation;
import com.evolveum.midpoint.schema.ObjectOperationOption;
import com.evolveum.midpoint.schema.ResultHandler;
import com.evolveum.midpoint.schema.SelectorOptions;
Expand Down Expand Up @@ -87,6 +88,7 @@ public interface ModelService {
String GET_OBJECT = CLASS_NAME_WITH_DOT + "getObject";
String COUNT_OBJECTS = CLASS_NAME_WITH_DOT + "countObjects";
String EXECUTE_CHANGES = CLASS_NAME_WITH_DOT + "executeChanges";
String EXECUTE_CHANGE = CLASS_NAME_WITH_DOT + "executeChange";
String RECOMPUTE = CLASS_NAME_WITH_DOT + "recompute";
String GET_PROPERTY_AVAILABLE_VALUES = CLASS_NAME_WITH_DOT + "getPropertyAvailableValues";
String LIST_OBJECTS = CLASS_NAME_WITH_DOT + "listObjects";
Expand Down Expand Up @@ -196,6 +198,8 @@ <T extends ObjectType> PrismObject<T> getObject(Class<T> type, String oid, Colle
* parent OperationResult (in/out)
* @param task
* Task instance. It gives context to the execution (e.g. security context)
* @return A collection of executed ObjectDeltaOperations (ObjectDelta + OperationResult). OIDs of newly created objects can be found
* in these ObjectDeltas (which may or may not be original ObjectDeltas passed to the method).
* @throws ObjectAlreadyExistsException
* object with specified identifiers already exists, cannot add
* @throws ObjectNotFoundException
Expand All @@ -212,15 +216,15 @@ <T extends ObjectType> PrismObject<T> getObject(Class<T> type, String oid, Colle
* Configuration error. E.g. misconfigured resource parameters, invalid policies, etc.
* @throws PolicyViolationException
* Policy violation was detected during processing of the object
* @throw SecurityViolationException
* @throws SecurityViolationException
* Security violation during operation execution. May be caused either by midPoint internal
* security mechanism but also by external mechanism (e.g. on the resource)
* @throws IllegalArgumentException
* wrong OID format, etc.
* @throws SystemException
* unknown error from underlying layers or other unexpected state
*/
void executeChanges(Collection<ObjectDelta<? extends ObjectType>> deltas, ModelExecuteOptions options, Task task, OperationResult parentResult)
Collection<ObjectDeltaOperation<? extends ObjectType>> executeChanges(Collection<ObjectDelta<? extends ObjectType>> deltas, ModelExecuteOptions options, Task task, OperationResult parentResult)
throws ObjectAlreadyExistsException, ObjectNotFoundException, SchemaException, ExpressionEvaluationException,
CommunicationException, ConfigurationException, PolicyViolationException, SecurityViolationException;

Expand Down
Expand Up @@ -28,14 +28,19 @@
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.ws.BindingProvider;

import com.evolveum.midpoint.xml.ns._public.common.api_types_3.ObjectDeltaOperationListType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.CredentialsType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectDeltaOperationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.PasswordType;
import com.evolveum.prism.xml.ns._public.query_3.SearchFilterType;
import com.evolveum.prism.xml.ns._public.types_3.ChangeTypeType;
import com.evolveum.prism.xml.ns._public.types_3.ItemPathType;
import com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType;
import com.evolveum.prism.xml.ns._public.types_3.PolyStringType;
import com.evolveum.prism.xml.ns._public.types_3.ProtectedStringType;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.Validate;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;
import org.apache.ws.security.WSConstants;
Expand Down Expand Up @@ -171,6 +176,37 @@ public static Element getFirstChildElement(Node parent) {

return null;
}

/**
* Retrieves OID created by model Web Service from the returned list of ObjectDeltaOperations.
*
* @param operationListType result of the model web service executeChanges call
* @param originalDelta original request used to find corresponding ObjectDeltaOperationType instance. Must be of ADD type.
* @return OID if found
*
* PRELIMINARY IMPLEMENTATION. Currently the first returned ADD delta with the same object type as original delta is returned.
*/
public static String getOidFromDeltaOperationList(ObjectDeltaOperationListType operationListType, ObjectDeltaType originalDelta) {
Validate.notNull(operationListType);
Validate.notNull(originalDelta);
if (originalDelta.getChangeType() != ChangeTypeType.ADD) {
throw new IllegalArgumentException("Original delta is not of ADD type");
}
if (originalDelta.getObjectToAdd() == null) {
throw new IllegalArgumentException("Original delta contains no object-to-be-added");
}
for (ObjectDeltaOperationType operationType : operationListType.getDeltaOperation()) {
ObjectDeltaType objectDeltaType = operationType.getObjectDelta();
if (objectDeltaType.getChangeType() == ChangeTypeType.ADD &&
objectDeltaType.getObjectToAdd() != null) {
ObjectType objectAdded = (ObjectType) objectDeltaType.getObjectToAdd();
if (objectAdded.getClass().equals(originalDelta.getObjectToAdd().getClass())) {
return objectAdded.getOid();
}
}
}
return null;
}

static {
try {
Expand Down
Expand Up @@ -34,6 +34,7 @@
import com.evolveum.midpoint.prism.query.QueryJaxbConvertor;
import com.evolveum.midpoint.schema.DeltaConvertor;
import com.evolveum.midpoint.schema.GetOperationOptions;
import com.evolveum.midpoint.schema.ObjectDeltaOperation;
import com.evolveum.midpoint.schema.SelectorOptions;
import com.evolveum.midpoint.schema.constants.ObjectTypes;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
Expand All @@ -55,12 +56,14 @@
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.xml.ns._public.common.api_types_3.ExecuteScriptsOptionsType;
import com.evolveum.midpoint.xml.ns._public.common.api_types_3.ObjectDeltaListType;
import com.evolveum.midpoint.xml.ns._public.common.api_types_3.ObjectDeltaOperationListType;
import com.evolveum.midpoint.xml.ns._public.common.api_types_3.ObjectListType;
import com.evolveum.midpoint.xml.ns._public.common.api_types_3.OutputFormatType;
import com.evolveum.midpoint.xml.ns._public.common.api_types_3.ScriptOutputsType;
import com.evolveum.midpoint.xml.ns._public.common.api_types_3.SelectorQualifiedGetOptionsType;
import com.evolveum.midpoint.xml.ns._public.common.api_types_3.SingleScriptOutputType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ModelExecuteOptionsType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectDeltaOperationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceObjectShadowChangeDescriptionType;
Expand Down Expand Up @@ -174,7 +177,7 @@ public void searchObjects(QName objectType, QueryType query, SelectorQualifiedGe
}

@Override
public OperationResultType executeChanges(ObjectDeltaListType deltaList, ModelExecuteOptionsType optionsType) throws FaultMessage {
public ObjectDeltaOperationListType executeChanges(ObjectDeltaListType deltaList, ModelExecuteOptionsType optionsType) throws FaultMessage {
notNullArgument(deltaList, "Object delta list must not be null.");

Task task = createTaskInstance(EXECUTE_CHANGES);
Expand All @@ -186,8 +189,15 @@ public OperationResultType executeChanges(ObjectDeltaListType deltaList, ModelEx
prismContext.adopt(delta);
}
ModelExecuteOptions options = ModelExecuteOptions.fromModelExecutionOptionsType(optionsType);
modelController.executeChanges((Collection) deltas, options, task, operationResult); // brutally eliminating type-safety compiler barking
return handleOperationResult(operationResult);
Collection<ObjectDeltaOperation<? extends ObjectType>> objectDeltaOperations = modelController.executeChanges((Collection) deltas, options, task, operationResult); // brutally eliminating type-safety compiler barking
ObjectDeltaOperationListType retval = new ObjectDeltaOperationListType();
for (ObjectDeltaOperation objectDeltaOperation : objectDeltaOperations) {
ObjectDeltaOperationType objectDeltaOperationType = new ObjectDeltaOperationType();
objectDeltaOperationType.setObjectDelta(DeltaConvertor.toObjectDeltaType(objectDeltaOperation.getObjectDelta()));
objectDeltaOperationType.setExecutionResult(objectDeltaOperation.getExecutionResult().createOperationResultType());
retval.getDeltaOperation().add(objectDeltaOperationType);
}
return retval;
} catch (Exception ex) {
LoggingUtils.logException(LOGGER, "# MODEL executeChanges() failed", ex);
auditLogout(task);
Expand Down
Expand Up @@ -30,6 +30,7 @@
import com.evolveum.midpoint.model.api.TaskService;
import com.evolveum.midpoint.model.api.WorkflowService;
import com.evolveum.midpoint.model.api.hooks.ReadHook;
import com.evolveum.midpoint.model.lens.LensProjectionContext;
import com.evolveum.midpoint.model.util.Utils;
import com.evolveum.midpoint.wf.api.WorkflowManager;
import com.evolveum.midpoint.xml.ns._public.model.model_context_3.LensContextType;
Expand Down Expand Up @@ -357,11 +358,13 @@ private void resolve(PrismObject<?> object, ItemPath path, SelectorOptions<GetOp
* @see com.evolveum.midpoint.model.api.ModelService#executeChanges(java.util.Collection, com.evolveum.midpoint.task.api.Task, com.evolveum.midpoint.schema.result.OperationResult)
*/
@Override
public void executeChanges(final Collection<ObjectDelta<? extends ObjectType>> deltas, ModelExecuteOptions options,
public Collection<ObjectDeltaOperation<? extends ObjectType>> executeChanges(final Collection<ObjectDelta<? extends ObjectType>> deltas, ModelExecuteOptions options,
Task task, OperationResult parentResult) throws ObjectAlreadyExistsException, ObjectNotFoundException,
SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException,
PolicyViolationException, SecurityViolationException {

Collection<ObjectDeltaOperation<? extends ObjectType>> retval = new ArrayList<>();

OperationResult result = parentResult.createSubresult(EXECUTE_CHANGES);
result.addParam(OperationResult.PARAM_OPTIONS, options);

Expand Down Expand Up @@ -401,6 +404,7 @@ public void run() {
auditRecord.addDeltas(ObjectDeltaOperation.cloneDeltaCollection(deltas));
auditService.audit(auditRecord, task);
for(ObjectDelta<? extends ObjectType> delta: deltas) {
OperationResult result1 = result.createSubresult(EXECUTE_CHANGE);
if (delta.isAdd()) {
RepoAddOptions repoOptions = new RepoAddOptions();
if (ModelExecuteOptions.isNoCrypt(options)) {
Expand All @@ -409,28 +413,30 @@ public void run() {
if (ModelExecuteOptions.isOverwrite(options)) {
repoOptions.setOverwrite(true);
}
securityEnforcer.authorize(ModelAuthorizationAction.ADD.getUrl(), null, delta.getObjectToAdd(), null, null, null, result);
String oid = cacheRepositoryService.addObject(delta.getObjectToAdd(), repoOptions, result);
securityEnforcer.authorize(ModelAuthorizationAction.ADD.getUrl(), null, delta.getObjectToAdd(), null, null, null, result1);
String oid = cacheRepositoryService.addObject(delta.getObjectToAdd(), repoOptions, result1);
delta.setOid(oid);
} else if (delta.isDelete()) {
PrismObject<? extends ObjectType> existingObject = cacheRepositoryService.getObject(delta.getObjectTypeClass(), delta.getOid(), null, result);
securityEnforcer.authorize(ModelAuthorizationAction.DELETE.getUrl(), null, existingObject, null, null, null, result);
PrismObject<? extends ObjectType> existingObject = cacheRepositoryService.getObject(delta.getObjectTypeClass(), delta.getOid(), null, result1);
securityEnforcer.authorize(ModelAuthorizationAction.DELETE.getUrl(), null, existingObject, null, null, null, result1);
if (ObjectTypes.isClassManagedByProvisioning(delta.getObjectTypeClass())) {
Utils.clearRequestee(task);
provisioning.deleteObject(delta.getObjectTypeClass(), delta.getOid(),
ProvisioningOperationOptions.createRaw(), null, task, result);
ProvisioningOperationOptions.createRaw(), null, task, result1);
} else {
cacheRepositoryService.deleteObject(delta.getObjectTypeClass(), delta.getOid(),
result);
result1);
}
} else if (delta.isModify()) {
PrismObject existingObject = cacheRepositoryService.getObject(delta.getObjectTypeClass(), delta.getOid(), null, result);
securityEnforcer.authorize(ModelAuthorizationAction.MODIFY.getUrl(), null, existingObject, delta, null, null, result);
PrismObject existingObject = cacheRepositoryService.getObject(delta.getObjectTypeClass(), delta.getOid(), null, result1);
securityEnforcer.authorize(ModelAuthorizationAction.MODIFY.getUrl(), null, existingObject, delta, null, null, result1);
cacheRepositoryService.modifyObject(delta.getObjectTypeClass(), delta.getOid(),
delta.getModifications(), result);
delta.getModifications(), result1);
} else {
throw new IllegalArgumentException("Wrong delta type "+delta.getChangeType()+" in "+delta);
}
result1.computeStatusIfUnknown();
retval.add(new ObjectDeltaOperation<>(delta, result1));
}
auditRecord.setTimestamp(null);
auditRecord.setOutcome(OperationResultStatus.SUCCESS);
Expand All @@ -442,7 +448,14 @@ public void run() {
LensContext<? extends ObjectType> context = contextFactory.createContext(deltas, options, task, result);
// Note: Request authorization happens inside clockwork
clockwork.run(context, task, result);


// prepare return value
if (context.getFocusContext() != null) {
retval.addAll(context.getFocusContext().getExecutedDeltas());
}
for (LensProjectionContext projectionContext : context.getProjectionContexts()) {
retval.addAll(projectionContext.getExecutedDeltas());
}
}

result.computeStatus();
Expand Down Expand Up @@ -485,6 +498,7 @@ public void run() {
} finally {
RepositoryCache.exit();
}
return retval;
}

@Override
Expand Down

0 comments on commit 9d5ed81

Please sign in to comment.