From 04e6abe1e2a741188b5662ca3c1bbf31352e8e19 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Mon, 14 Sep 2015 15:09:10 +0200 Subject: [PATCH] Fixing provisioning test failures. Working around XMLGregorianCalendarImpl clone problem in some environments. Started implementation of task state display (unfinished, uncompilable). --- .../web/page/admin/server/PageTaskEdit.html | 6 +- .../web/page/admin/server/PageTaskEdit.java | 13 +- .../page/admin/server/PageTaskEdit.properties | 2 +- .../server/currentState/TaskStatePanel.html | 26 ++++ .../server/currentState/TaskStatePanel.java | 80 +++++++++++ .../currentState/TaskStatePanel.properties | 18 +++ .../midpoint/prism/util/CloneUtil.java | 11 ++ .../midpoint/prism/xml/XmlTypeConverter.java | 8 ++ .../provisioning/impl/StateReporter.java | 35 ++--- .../ucf/impl/ConnectorInstanceIcfImpl.java | 135 ++++++++++++------ 10 files changed, 258 insertions(+), 76 deletions(-) create mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/currentState/TaskStatePanel.html create mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/currentState/TaskStatePanel.java create mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/currentState/TaskStatePanel.properties diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTaskEdit.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTaskEdit.html index 922b77c4ccf..92e6f5ed476 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTaskEdit.html +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTaskEdit.html @@ -142,7 +142,7 @@


- + f @@ -180,8 +180,8 @@

-

-
+

+
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTaskEdit.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTaskEdit.java index c01b40be515..8ac0b5221e1 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTaskEdit.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTaskEdit.java @@ -57,6 +57,7 @@ import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour; import com.evolveum.midpoint.web.page.PageBase; import com.evolveum.midpoint.web.page.PageTemplate; +import com.evolveum.midpoint.web.page.admin.server.currentState.TaskStatePanel; import com.evolveum.midpoint.web.page.admin.server.dto.*; import com.evolveum.midpoint.web.page.admin.server.subtasks.SubtasksPanel; import com.evolveum.midpoint.web.page.admin.server.workflowInformation.WorkflowInformationPanel; @@ -126,6 +127,7 @@ public class PageTaskEdit extends PageAdminTasks { private static final String ID_SUBTASKS_PANEL = "subtasksPanel"; private static final String ID_WORKFLOW_INFORMATION_LABEL = "workflowInformationLabel"; private static final String ID_WORKFLOW_INFORMATION_PANEL = "workflowInformationPanel"; + private static final String ID_TASK_STATE_PANEL = "taskStatePanel"; private static final String ID_NAME = "name"; private static final String ID_NAME_LABEL = "nameLabel"; private static final String ID_DESCRIPTION = "description"; @@ -287,14 +289,9 @@ public boolean isVisible() { panel.add(modelOpBehaviour); mainForm.add(panel); - SortableDataProvider provider = new ListDataProvider<>(this, - new PropertyModel>(model, "opResult")); - TablePanel result = new TablePanel<>("operationResult", provider, initResultColumns()); - result.setStyle("padding-top: 0px;"); - result.setShowPaging(false); - result.setOutputMarkupId(true); - result.add(hiddenWhenEditing); - mainForm.add(result); + TaskStatePanel taskStatePanel = new TaskStatePanel(ID_TASK_STATE_PANEL, model); + taskStatePanel.add(hiddenWhenEditing); + mainForm.add(taskStatePanel); DropDownChoice threadStop = new DropDownChoice<>("threadStop", new Model() { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTaskEdit.properties b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTaskEdit.properties index 66f6fb2f497..0e83415e5b2 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTaskEdit.properties +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTaskEdit.properties @@ -55,7 +55,7 @@ pageTaskEdit.tightlyBound=Tightly bound pageTaskEdit.runUntilNodeDown=Run only until node down pageTaskEdit.threadStop=Thread stop action -pageTaskEdit.opResult=Operation result +pageTaskEdit.taskState=Task state pageTaskEdit.modelOperationStatusLabel=Model operation status pageTaskEdit.subtasksLabel=Subtasks diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/currentState/TaskStatePanel.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/currentState/TaskStatePanel.html new file mode 100644 index 00000000000..69d1a571a1f --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/currentState/TaskStatePanel.html @@ -0,0 +1,26 @@ + + + + + + + +

+
+ + + diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/currentState/TaskStatePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/currentState/TaskStatePanel.java new file mode 100644 index 00000000000..048f72cb067 --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/currentState/TaskStatePanel.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2010-2015 Evolveum + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.evolveum.midpoint.web.page.admin.server.currentState; + +import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.web.component.data.TablePanel; +import com.evolveum.midpoint.web.component.data.column.LinkPanel; +import com.evolveum.midpoint.web.component.util.ListDataProvider; +import com.evolveum.midpoint.web.component.util.SimplePanel; +import com.evolveum.midpoint.web.component.wf.WfDeltasPanel; +import com.evolveum.midpoint.web.component.wf.WfHistoryEventDto; +import com.evolveum.midpoint.web.component.wf.WfHistoryPanel; +import com.evolveum.midpoint.web.page.PageBase; +import com.evolveum.midpoint.web.page.admin.server.dto.TaskDto; +import com.evolveum.midpoint.web.page.admin.workflow.PageProcessInstance; +import com.evolveum.midpoint.web.util.OnePageParameterEncoder; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.PropertyModel; +import org.apache.wicket.model.StringResourceModel; +import org.apache.wicket.request.mapper.parameter.PageParameters; + +import java.util.List; + +/** + * @author mederly + */ +public class TaskStatePanel extends SimplePanel { + + private static final String ID_DELTAS_PANEL = "deltasPanel"; + private static final String ID_HISTORY_PANEL = "historyPanel"; + private static final String ID_PAGE_PROCESS_INSTANCE_LINK = "pageProcessInstanceLink"; + + public TaskStatePanel(String id, IModel model) { + super(id, model); + } + + @Override + protected void initLayout() { + + SortableDataProvider provider = new ListDataProvider<>(this, + new PropertyModel>(model, "opResult")); + TablePanel result = new TablePanel<>("operationResult", provider, initResultColumns()); + result.setStyle("padding-top: 0px;"); + result.setShowPaging(false); + result.setOutputMarkupId(true); + result.add(hiddenWhenEditing); + mainForm.add(result); + + add(new LinkPanel(ID_PAGE_PROCESS_INSTANCE_LINK, new StringResourceModel("WorkflowInformationPanel.link.processInstance", getModel())) { + @Override + public void onClick(AjaxRequestTarget target) { + String pid = TaskStatePanel.this.getModel().getObject().getWorkflowProcessInstanceId(); + boolean finished = TaskStatePanel.this.getModel().getObject().isWorkflowProcessInstanceFinished(); + PageParameters parameters = new PageParameters(); + parameters.add(OnePageParameterEncoder.PARAMETER, pid); + parameters.add(PageProcessInstance.PARAM_PROCESS_INSTANCE_FINISHED, finished); + TaskStatePanel.this.setResponsePage(new PageProcessInstance(parameters, (PageBase) TaskStatePanel.this.getPage())); + } + }); + + add(new WfDeltasPanel(ID_DELTAS_PANEL, getModel())); + add(new WfHistoryPanel(ID_HISTORY_PANEL, new PropertyModel>(getModel(), TaskDto.F_WORKFLOW_HISTORY))); + } +} diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/currentState/TaskStatePanel.properties b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/currentState/TaskStatePanel.properties new file mode 100644 index 00000000000..752b403230e --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/currentState/TaskStatePanel.properties @@ -0,0 +1,18 @@ +# +# Copyright (c) 2010-2015 Evolveum +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + +TaskStatePanel.opResult=Operation result \ No newline at end of file diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/util/CloneUtil.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/util/CloneUtil.java index 33ac44b351b..45827e0b1bf 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/util/CloneUtil.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/util/CloneUtil.java @@ -23,6 +23,7 @@ import java.util.Collection; import java.util.List; +import com.evolveum.midpoint.prism.xml.XmlTypeConverter; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import org.apache.commons.lang.SerializationUtils; @@ -37,6 +38,7 @@ import com.evolveum.prism.xml.ns._public.types_3.RawType; import org.springframework.util.ClassUtils; +import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.QName; /** @@ -98,6 +100,15 @@ public static T clone(T orig) { if (orig instanceof Definition) { return (T) ((Definition)orig).clone(); } + /* + * In some environments we cannot clone XMLGregorianCalendar because of this: + * Error when cloning class org.apache.xerces.jaxp.datatype.XMLGregorianCalendarImpl, will try serialization instead. + * java.lang.IllegalAccessException: Class com.evolveum.midpoint.prism.util.CloneUtil can not access a member of + * class org.apache.xerces.jaxp.datatype.XMLGregorianCalendarImpl with modifiers "public" + */ + if (orig instanceof XMLGregorianCalendar) { + return (T) XmlTypeConverter.createXMLGregorianCalendar((XMLGregorianCalendar) orig); + } if (orig instanceof Cloneable) { T clone = javaLangClone(orig); if (clone != null) { diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/xml/XmlTypeConverter.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/xml/XmlTypeConverter.java index 453d92be8af..2343434961d 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/xml/XmlTypeConverter.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/xml/XmlTypeConverter.java @@ -463,6 +463,14 @@ public static XMLGregorianCalendar createXMLGregorianCalendar(String string) { public static XMLGregorianCalendar createXMLGregorianCalendar(GregorianCalendar cal) { return getDatatypeFactory().newXMLGregorianCalendar(cal); } + + // in some environments, XMLGregorianCalendar.clone does not work + public static XMLGregorianCalendar createXMLGregorianCalendar(XMLGregorianCalendar cal) { + if (cal == null) { + return null; + } + return getDatatypeFactory().newXMLGregorianCalendar(cal.toGregorianCalendar()); // TODO find a better way + } public static XMLGregorianCalendar createXMLGregorianCalendar(int year, int month, int day, int hour, int minute, int second, int millisecond, int timezone) { diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/StateReporter.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/StateReporter.java index a3d1182dd42..26b4d671f2b 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/StateReporter.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/StateReporter.java @@ -23,6 +23,7 @@ import com.evolveum.midpoint.util.logging.TraceManager; import org.identityconnectors.framework.common.objects.Uid; +import javax.xml.namespace.QName; import java.util.Date; /** @@ -83,11 +84,7 @@ public void recordIcfOperationStart(ProvisioningOperation operation, ObjectClass if (uid != null) { object = " " + uid.getUidValue(); } - recordState("Starting " + operation + " of " + objectClassDef.getTypeName().getLocalPart() + object + " on " + getResourceName()); - } - - public void recordIcfOperationStart(ProvisioningOperation operation, ObjectClassComplexTypeDefinition objectClassDefinition) { - recordIcfOperationStart(operation, objectClassDefinition, null); + recordState("Starting " + operation + " of " + getObjectClassName(objectClassDef) + object + " on " + getResourceName()); } // we just add duration, not count (we'll do this on end) @@ -118,14 +115,22 @@ public void recordIcfOperationResume(ProvisioningOperation operation, ObjectClas recordState("Continuing " + operation + " of " + objectClassDef.getTypeName().getLocalPart() + " on " + getResourceName()); } + private String getObjectClassName(ObjectClassComplexTypeDefinition objectClassDef) { + return objectClassDef != null && objectClassDef.getTypeName() != null ? objectClassDef.getTypeName().getLocalPart() : "(null)"; + } + + private QName getObjectClassQName(ObjectClassComplexTypeDefinition objectClassDef) { + return objectClassDef != null ? objectClassDef.getTypeName() : null; + } + public void recordIcfOperationEnd(ProvisioningOperation operation, ObjectClassComplexTypeDefinition objectClassDef, Throwable ex, Uid uid) { long duration = -1L; if (lastOperation != operation) { LOGGER.warn("Finishing operation other than current: finishing {}, last recorded {}", operation, lastOperation); - } else if (lastObjectClass == null || !lastObjectClass.getTypeName().equals(objectClassDef.getTypeName())) { + } else if (objectClassDef != null && (lastObjectClass == null || !lastObjectClass.getTypeName().equals(objectClassDef.getTypeName()))) { LOGGER.warn("Finishing operation on object class other than current: finishing on {}, last recorded {}", - objectClassDef.getTypeName(), lastObjectClass != null ? lastObjectClass.getTypeName() : "(null)"); + getObjectClassName(objectClassDef), getObjectClassName(lastObjectClass)); } else { duration = System.currentTimeMillis() - lastStarted.getTime(); } @@ -146,25 +151,13 @@ public void recordIcfOperationEnd(ProvisioningOperation operation, ObjectClassCo if (uid != null) { object = " " + uid.getUidValue(); } - recordState(finished + " " + operation + " of " + objectClassDef.getTypeName().getLocalPart() + object + " on " + getResourceName() + durationString); + recordState(finished + " " + operation + " of " + getObjectClassName(objectClassDef) + object + " on " + getResourceName() + durationString); if (task != null && duration >= 0) { - task.recordProvisioningOperation(resourceOid, getResourceName(), objectClassDef.getTypeName(), lastOperation, ex == null, 1, duration); + task.recordProvisioningOperation(resourceOid, getResourceName(), getObjectClassQName(objectClassDef), lastOperation, ex == null, 1, duration); } lastOperation = null; } - public void recordIcfOperationEnd(ProvisioningOperation operation, ObjectClassComplexTypeDefinition objectClassDef, Uid uid) { - recordIcfOperationEnd(operation, objectClassDef, null, uid); - } - - public void recordIcfOperationEnd(ProvisioningOperation operation, ObjectClassComplexTypeDefinition objectClassDefinition) { - recordIcfOperationEnd(operation, objectClassDefinition, null, null); - } - - public void recordIcfOperationEnd(ProvisioningOperation operation, ObjectClassComplexTypeDefinition objectClassDef, Throwable ex) { - recordIcfOperationEnd(operation, objectClassDef, ex, null); - } - private void recordState(String message) { if (task != null) { task.recordState(message); diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/ConnectorInstanceIcfImpl.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/ConnectorInstanceIcfImpl.java index 01b763fc100..e5e50887b81 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/ConnectorInstanceIcfImpl.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/ConnectorInstanceIcfImpl.java @@ -584,19 +584,19 @@ private void retrieveResourceSchema(List generateObjectClasses, Operation // from the resource). InternalMonitor.recordConnectorOperation("schema"); // TODO have context present - //reporter.recordIcfOperationStart(ProvisioningOperation.ICF_GET_SCHEMA, null); + //recordIcfOperationStart(reporter, ProvisioningOperation.ICF_GET_SCHEMA, null); icfSchema = icfConnectorFacade.schema(); - //reporter.recordIcfOperationEnd(ProvisioningOperation.ICF_GET_SCHEMA, null); + //recordIcfOperationEnd(reporter, ProvisioningOperation.ICF_GET_SCHEMA, null); icfResult.recordSuccess(); } catch (UnsupportedOperationException ex) { - //reporter.recordIcfOperationEnd(ProvisioningOperation.ICF_GET_SCHEMA, null, ex); + //recordIcfOperationEnd(reporter, ProvisioningOperation.ICF_GET_SCHEMA, null, ex); // The connector does no support schema() operation. icfResult.recordStatus(OperationResultStatus.NOT_APPLICABLE, ex.getMessage()); resetResourceSchema(); return; } catch (Throwable ex) { - //reporter.recordIcfOperationEnd(ProvisioningOperation.ICF_GET_SCHEMA, null, ex); + //recordIcfOperationEnd(reporter, ProvisioningOperation.ICF_GET_SCHEMA, null, ex); // conditions. // Therefore this kind of heavy artillery is necessary. // ICF interface does not specify exceptions or other error @@ -1198,13 +1198,13 @@ private ConnectorObject fetchConnectorObject(StateReporter reporter, ObjectClass // Invoke the ICF connector InternalMonitor.recordConnectorOperation("getObject"); - reporter.recordIcfOperationStart(ProvisioningOperation.ICF_GET, objectClassDefinition, uid); + recordIcfOperationStart(reporter, ProvisioningOperation.ICF_GET, objectClassDefinition, uid); co = icfConnectorFacade.getObject(icfObjectClass, uid, options); - reporter.recordIcfOperationEnd(ProvisioningOperation.ICF_GET, objectClassDefinition, uid); + recordIcfOperationEnd(reporter, ProvisioningOperation.ICF_GET, objectClassDefinition, uid); icfResult.recordSuccess(); } catch (Throwable ex) { - reporter.recordIcfOperationEnd(ProvisioningOperation.ICF_GET, objectClassDefinition, ex, uid); + recordIcfOperationEnd(reporter, ProvisioningOperation.ICF_GET, objectClassDefinition, ex, uid); String desc = this.getHumanReadableName() + " while getting object identified by ICF UID '"+uid.getUidValue()+"'"; Throwable midpointEx = processIcfException(ex, desc, icfResult); icfResult.computeStatus("Add object failed"); @@ -1237,7 +1237,7 @@ private ConnectorObject fetchConnectorObject(StateReporter reporter, ObjectClass return co; } - private void convertToIcfAttrsToGet(ObjectClassComplexTypeDefinition objectClassDefinition, + private void convertToIcfAttrsToGet(ObjectClassComplexTypeDefinition objectClassDefinition, AttributesToReturn attributesToReturn, OperationOptionsBuilder optionsBuilder) throws SchemaException { if (attributesToReturn == null) { return; @@ -1407,12 +1407,12 @@ public Collection> addObject(PrismObject modifyObject(ObjectClassComplexTypeDef InternalMonitor.recordConnectorOperation("addAttributeValues"); // Invoking ConnId - reporter.recordIcfOperationStart(ProvisioningOperation.ICF_UPDATE, objectClassDef, uid); + recordIcfOperationStart(reporter, ProvisioningOperation.ICF_UPDATE, objectClassDef, uid); uid = icfConnectorFacade.addAttributeValues(objClass, uid, attributesToAdd, options); - reporter.recordIcfOperationEnd(ProvisioningOperation.ICF_UPDATE, objectClassDef, null, uid); + recordIcfOperationEnd(reporter, ProvisioningOperation.ICF_UPDATE, objectClassDef, null, uid); icfResult.recordSuccess(); } } catch (Throwable ex) { - reporter.recordIcfOperationEnd(ProvisioningOperation.ICF_UPDATE, objectClassDef, ex, uid); + recordIcfOperationEnd(reporter, ProvisioningOperation.ICF_UPDATE, objectClassDef, ex, uid); String desc = this.getHumanReadableName() + " while adding attribute values to object identified by ICF UID '"+uid.getUidValue()+"'"; Throwable midpointEx = processIcfException(ex, desc, icfResult); result.computeStatus("Adding attribute values failed"); @@ -1784,13 +1784,13 @@ public Set modifyObject(ObjectClassComplexTypeDef try { // Call ICF InternalMonitor.recordConnectorOperation("update"); - reporter.recordIcfOperationStart(ProvisioningOperation.ICF_UPDATE, objectClassDef, uid); + recordIcfOperationStart(reporter, ProvisioningOperation.ICF_UPDATE, objectClassDef, uid); uid = icfConnectorFacade.update(objClass, uid, attributesToUpdate, options); - reporter.recordIcfOperationEnd(ProvisioningOperation.ICF_UPDATE, objectClassDef, null, uid); + recordIcfOperationEnd(reporter, ProvisioningOperation.ICF_UPDATE, objectClassDef, null, uid); icfResult.recordSuccess(); } catch (Throwable ex) { - reporter.recordIcfOperationEnd(ProvisioningOperation.ICF_UPDATE, objectClassDef, ex, uid); + recordIcfOperationEnd(reporter, ProvisioningOperation.ICF_UPDATE, objectClassDef, ex, uid); String desc = this.getHumanReadableName() + " while updating object identified by ICF UID '"+uid.getUidValue()+"'"; Throwable midpointEx = processIcfException(ex, desc, icfResult); result.computeStatus("Update failed"); @@ -1839,13 +1839,13 @@ public Set modifyObject(ObjectClassComplexTypeDef } InternalMonitor.recordConnectorOperation("removeAttributeValues"); - reporter.recordIcfOperationStart(ProvisioningOperation.ICF_UPDATE, objectClassDef, uid); + recordIcfOperationStart(reporter, ProvisioningOperation.ICF_UPDATE, objectClassDef, uid); uid = icfConnectorFacade.removeAttributeValues(objClass, uid, attributesToRemove, options); - reporter.recordIcfOperationEnd(ProvisioningOperation.ICF_UPDATE, objectClassDef, null, uid); + recordIcfOperationEnd(reporter, ProvisioningOperation.ICF_UPDATE, objectClassDef, null, uid); icfResult.recordSuccess(); } } catch (Throwable ex) { - reporter.recordIcfOperationEnd(ProvisioningOperation.ICF_UPDATE, objectClassDef, ex, uid); + recordIcfOperationEnd(reporter, ProvisioningOperation.ICF_UPDATE, objectClassDef, ex, uid); String desc = this.getHumanReadableName() + " while removing attribute values from object identified by ICF UID '"+uid.getUidValue()+"'"; Throwable midpointEx = processIcfException(ex, desc, icfResult); result.computeStatus("Removing attribute values failed"); @@ -1946,14 +1946,14 @@ public void deleteObject(ObjectClassComplexTypeDefinition objectClass, Collectio try { InternalMonitor.recordConnectorOperation("delete"); - reporter.recordIcfOperationStart(ProvisioningOperation.ICF_DELETE, objectClass, uid); + recordIcfOperationStart(reporter, ProvisioningOperation.ICF_DELETE, objectClass, uid); icfConnectorFacade.delete(objClass, uid, new OperationOptionsBuilder().build()); - reporter.recordIcfOperationEnd(ProvisioningOperation.ICF_DELETE, objectClass, null, uid); + recordIcfOperationEnd(reporter, ProvisioningOperation.ICF_DELETE, objectClass, null, uid); icfResult.recordSuccess(); } catch (Throwable ex) { - reporter.recordIcfOperationEnd(ProvisioningOperation.ICF_DELETE, objectClass, ex, uid); + recordIcfOperationEnd(reporter, ProvisioningOperation.ICF_DELETE, objectClass, ex, uid); String desc = this.getHumanReadableName() + " while deleting object identified by ICF UID '"+uid.getUidValue()+"'"; Throwable midpointEx = processIcfException(ex, desc, icfResult); result.computeStatus("Removing attribute values failed"); @@ -2009,13 +2009,13 @@ public PrismProperty fetchCurrentToken(ObjectClassComplexTypeDefinition o SyncToken syncToken = null; try { InternalMonitor.recordConnectorOperation("getLatestSyncToken"); - reporter.recordIcfOperationStart(ProvisioningOperation.ICF_GET_LATEST_SYNC_TOKEN, objectClassDef); + recordIcfOperationStart(reporter, ProvisioningOperation.ICF_GET_LATEST_SYNC_TOKEN, objectClassDef); syncToken = icfConnectorFacade.getLatestSyncToken(icfObjectClass); - reporter.recordIcfOperationEnd(ProvisioningOperation.ICF_GET_LATEST_SYNC_TOKEN, objectClassDef); + recordIcfOperationEnd(reporter, ProvisioningOperation.ICF_GET_LATEST_SYNC_TOKEN, objectClassDef); icfResult.recordSuccess(); icfResult.addReturn("syncToken", syncToken==null?null:String.valueOf(syncToken.getValue())); } catch (Throwable ex) { - reporter.recordIcfOperationEnd(ProvisioningOperation.ICF_GET_LATEST_SYNC_TOKEN, objectClassDef, ex); + recordIcfOperationEnd(reporter, ProvisioningOperation.ICF_GET_LATEST_SYNC_TOKEN, objectClassDef, ex); Throwable midpointEx = processIcfException(ex, this, icfResult); result.computeStatus(); // Do some kind of acrobatics to do proper throwing of checked @@ -2095,14 +2095,14 @@ public boolean handle(SyncDelta delta) { SyncToken lastReceivedToken; try { InternalMonitor.recordConnectorOperation("sync"); - reporter.recordIcfOperationStart(ProvisioningOperation.ICF_SYNC, objectClass); + recordIcfOperationStart(reporter, ProvisioningOperation.ICF_SYNC, objectClass); lastReceivedToken = icfConnectorFacade.sync(icfObjectClass, syncToken, syncHandler, options); - reporter.recordIcfOperationEnd(ProvisioningOperation.ICF_SYNC, objectClass); + recordIcfOperationEnd(reporter, ProvisioningOperation.ICF_SYNC, objectClass); icfResult.recordSuccess(); icfResult.addReturn(OperationResult.RETURN_COUNT, syncDeltas.size()); } catch (Throwable ex) { - reporter.recordIcfOperationEnd(ProvisioningOperation.ICF_SYNC, objectClass, ex); + recordIcfOperationEnd(reporter, ProvisioningOperation.ICF_SYNC, objectClass, ex); Throwable midpointEx = processIcfException(ex, this, icfResult); result.computeStatus(); // Do some kind of acrobatics to do proper throwing of checked @@ -2209,7 +2209,7 @@ public SearchResultMetadata search(final ObjectClassCompl public boolean handle(ConnectorObject connectorObject) { // Convert ICF-specific connector object to a generic // ResourceObject - reporter.recordIcfOperationSuspend(ProvisioningOperation.ICF_SEARCH, objectClassDefinition); + recordIcfOperationSuspend(reporter, ProvisioningOperation.ICF_SEARCH, objectClassDefinition); int count = countHolder.getValue(); countHolder.setValue(count+1); if (!useConnectorPaging) { @@ -2244,7 +2244,7 @@ public boolean handle(ConnectorObject connectorObject) { } private void recordResume() { - reporter.recordIcfOperationResume(ProvisioningOperation.ICF_SEARCH, objectClassDefinition); + recordIcfOperationResume(reporter, ProvisioningOperation.ICF_SEARCH, objectClassDefinition); } }; @@ -2303,19 +2303,19 @@ private void recordResume() { try { InternalMonitor.recordConnectorOperation("search"); - reporter.recordIcfOperationStart(ProvisioningOperation.ICF_SEARCH, objectClassDefinition); + recordIcfOperationStart(reporter, ProvisioningOperation.ICF_SEARCH, objectClassDefinition); icfSearchResult = icfConnectorFacade.search(icfObjectClass, filter, icfHandler, options); - reporter.recordIcfOperationEnd(ProvisioningOperation.ICF_SEARCH, objectClassDefinition); + recordIcfOperationEnd(reporter, ProvisioningOperation.ICF_SEARCH, objectClassDefinition); icfResult.recordSuccess(); } catch (IntermediateException inex) { - reporter.recordIcfOperationEnd(ProvisioningOperation.ICF_SEARCH, objectClassDefinition, inex); + recordIcfOperationEnd(reporter, ProvisioningOperation.ICF_SEARCH, objectClassDefinition, inex); SchemaException ex = (SchemaException) inex.getCause(); icfResult.recordFatalError(ex); result.recordFatalError(ex); throw ex; } catch (Throwable ex) { - reporter.recordIcfOperationEnd(ProvisioningOperation.ICF_SEARCH, objectClassDefinition, ex); + recordIcfOperationEnd(reporter, ProvisioningOperation.ICF_SEARCH, objectClassDefinition, ex); Throwable midpointEx = processIcfException(ex, this, icfResult); result.computeStatus(); // Do some kind of acrobatics to do proper throwing of checked @@ -2420,9 +2420,9 @@ public boolean handle(ConnectorObject connectorObject) { } }; InternalMonitor.recordConnectorOperation("search"); - reporter.recordIcfOperationStart(ProvisioningOperation.ICF_SEARCH, objectClassDefinition); + recordIcfOperationStart(reporter, ProvisioningOperation.ICF_SEARCH, objectClassDefinition); SearchResult searchResult = icfConnectorFacade.search(icfObjectClass, filter, icfHandler, options); - reporter.recordIcfOperationEnd(ProvisioningOperation.ICF_SEARCH, objectClassDefinition); + recordIcfOperationEnd(reporter, ProvisioningOperation.ICF_SEARCH, objectClassDefinition); if (searchResult == null || searchResult.getRemainingPagedResults() == -1) { throw new UnsupportedOperationException("Connector does not seem to support paged searches or does not provide object count information"); @@ -2432,18 +2432,18 @@ public boolean handle(ConnectorObject connectorObject) { icfResult.recordSuccess(); } catch (IntermediateException inex) { - reporter.recordIcfOperationEnd(ProvisioningOperation.ICF_SEARCH, objectClassDefinition, inex); + recordIcfOperationEnd(reporter, ProvisioningOperation.ICF_SEARCH, objectClassDefinition, inex); SchemaException ex = (SchemaException) inex.getCause(); icfResult.recordFatalError(ex); result.recordFatalError(ex); throw ex; } catch (UnsupportedOperationException uoe) { - reporter.recordIcfOperationEnd(ProvisioningOperation.ICF_SEARCH, objectClassDefinition, uoe); + recordIcfOperationEnd(reporter, ProvisioningOperation.ICF_SEARCH, objectClassDefinition, uoe); icfResult.recordFatalError(uoe); result.recordFatalError(uoe); throw uoe; } catch (Throwable ex) { - reporter.recordIcfOperationEnd(ProvisioningOperation.ICF_SEARCH, objectClassDefinition, ex); + recordIcfOperationEnd(reporter, ProvisioningOperation.ICF_SEARCH, objectClassDefinition, ex); Throwable midpointEx = processIcfException(ex, this, icfResult); result.computeStatus(); // Do some kind of acrobatics to do proper throwing of checked @@ -2851,7 +2851,7 @@ private Object executeScriptIcf(StateReporter reporter, ExecuteProvisioningScrip LOGGER.trace("Running script ({})", icfOpName); - reporter.recordIcfOperationStart(ProvisioningOperation.ICF_SCRIPT, null); + recordIcfOperationStart(reporter, ProvisioningOperation.ICF_SCRIPT, null); if (scriptOperation.isConnectorHost()) { InternalMonitor.recordConnectorOperation("runScriptOnConnector"); output = icfConnectorFacade.runScriptOnConnector(scriptContext, new OperationOptionsBuilder().build()); @@ -2859,7 +2859,7 @@ private Object executeScriptIcf(StateReporter reporter, ExecuteProvisioningScrip InternalMonitor.recordConnectorOperation("runScriptOnResource"); output = icfConnectorFacade.runScriptOnResource(scriptContext, new OperationOptionsBuilder().build()); } - reporter.recordIcfOperationEnd(ProvisioningOperation.ICF_SCRIPT, null); + recordIcfOperationEnd(reporter, ProvisioningOperation.ICF_SCRIPT, null); icfResult.recordSuccess(); @@ -2869,7 +2869,7 @@ private Object executeScriptIcf(StateReporter reporter, ExecuteProvisioningScrip } catch (Throwable ex) { - reporter.recordIcfOperationEnd(ProvisioningOperation.ICF_SCRIPT, null, ex); + recordIcfOperationEnd(reporter, ProvisioningOperation.ICF_SCRIPT, null, ex); if (LOGGER.isDebugEnabled()) { LOGGER.debug("Finished running script ({}), ERROR: {}", icfOpName, ex.getMessage()); @@ -3253,4 +3253,53 @@ public void dispose() { // Nothing to do } + private void recordIcfOperationStart(StateReporter reporter, ProvisioningOperation operation, ObjectClassComplexTypeDefinition objectClassDefinition, Uid uid) { + if (reporter != null) { + reporter.recordIcfOperationStart(operation, objectClassDefinition, uid); + } + } + + private void recordIcfOperationStart(StateReporter reporter, ProvisioningOperation operation, ObjectClassComplexTypeDefinition objectClassDefinition) { + if (reporter != null) { + reporter.recordIcfOperationStart(operation, objectClassDefinition, null); + } + } + + private void recordIcfOperationResume(StateReporter reporter, ProvisioningOperation operation, ObjectClassComplexTypeDefinition objectClassDefinition) { + if (reporter != null) { + reporter.recordIcfOperationResume(operation, objectClassDefinition); + } + } + + private void recordIcfOperationSuspend(StateReporter reporter, ProvisioningOperation operation, ObjectClassComplexTypeDefinition objectClassDefinition) { + if (reporter != null) { + reporter.recordIcfOperationSuspend(operation, objectClassDefinition); + } + } + + private void recordIcfOperationEnd(StateReporter reporter, ProvisioningOperation operation, ObjectClassComplexTypeDefinition objectClassDefinition, Uid uid) { + if (reporter != null) { + reporter.recordIcfOperationEnd(operation, objectClassDefinition, null, uid); + } + } + + private void recordIcfOperationEnd(StateReporter reporter, ProvisioningOperation operation, ObjectClassComplexTypeDefinition objectClassDefinition, Throwable ex) { + if (reporter != null) { + reporter.recordIcfOperationEnd(operation, objectClassDefinition, ex, null); + } + } + + private void recordIcfOperationEnd(StateReporter reporter, ProvisioningOperation operation, ObjectClassComplexTypeDefinition objectClassDefinition, Throwable ex, Uid uid) { + if (reporter != null) { + reporter.recordIcfOperationEnd(operation, objectClassDefinition, ex, uid); + } + } + + + private void recordIcfOperationEnd(StateReporter reporter, ProvisioningOperation operation, ObjectClassComplexTypeDefinition objectClassDefinition) { + if (reporter != null) { + reporter.recordIcfOperationEnd(operation, objectClassDefinition, null, null); + } + } + }