use of com.evolveum.midpoint.util.exception.SystemException in project midpoint by Evolveum.
the class SynchronizationServiceImpl method notifyChange.
@Override
public void notifyChange(ResourceObjectShadowChangeDescription change, Task task, OperationResult parentResult) {
validate(change);
Validate.notNull(parentResult, "Parent operation result must not be null.");
boolean logDebug = isLogDebug(change);
if (logDebug) {
LOGGER.debug("SYNCHRONIZATION: received change notification {}", change);
} else {
LOGGER.trace("SYNCHRONIZATION: received change notification {}", change);
}
OperationResult subResult = parentResult.createSubresult(NOTIFY_CHANGE);
PrismObject<? extends ShadowType> currentShadow = change.getCurrentShadow();
PrismObject<? extends ShadowType> applicableShadow = currentShadow;
if (applicableShadow == null) {
// We need this e.g. in case of delete
applicableShadow = change.getOldShadow();
}
SynchronizationEventInformation eventInfo = new SynchronizationEventInformation(applicableShadow, change.getSourceChannel(), task);
try {
ResourceType resourceType = change.getResource().asObjectable();
PrismObject<SystemConfigurationType> configuration = systemObjectCache.getSystemConfiguration(subResult);
ObjectSynchronizationType synchronizationPolicy = determineSynchronizationPolicy(resourceType, applicableShadow, configuration, task, subResult);
if (LOGGER.isTraceEnabled()) {
String policyDesc = null;
if (synchronizationPolicy != null) {
if (synchronizationPolicy.getName() == null) {
policyDesc = "(kind=" + synchronizationPolicy.getKind() + ", intent=" + synchronizationPolicy.getIntent() + ", objectclass=" + synchronizationPolicy.getObjectClass() + ")";
} else {
policyDesc = synchronizationPolicy.getName();
}
}
LOGGER.trace("SYNCHRONIZATION determined policy: {}", policyDesc);
}
if (synchronizationPolicy == null) {
String message = "SYNCHRONIZATION no matching policy for " + applicableShadow + " (" + applicableShadow.asObjectable().getObjectClass() + ") " + " on " + resourceType + ", ignoring change from channel " + change.getSourceChannel();
LOGGER.debug(message);
subResult.recordStatus(OperationResultStatus.NOT_APPLICABLE, message);
eventInfo.setNoSynchronizationPolicy();
eventInfo.record(task);
return;
}
if (!isSynchronizationEnabled(synchronizationPolicy)) {
String message = "SYNCHRONIZATION is not enabled for " + resourceType + " ignoring change from channel " + change.getSourceChannel();
LOGGER.debug(message);
subResult.recordStatus(OperationResultStatus.NOT_APPLICABLE, message);
eventInfo.setSynchronizationNotEnabled();
eventInfo.record(task);
return;
}
// defined in task
if (!satisfyTaskConstraints(synchronizationPolicy, task)) {
LOGGER.trace("SYNCHRONIZATION skipping {} because it does not match kind/intent defined in task", new Object[] { applicableShadow });
subResult.recordStatus(OperationResultStatus.NOT_APPLICABLE, "Skipped because it does not match objectClass/kind/intent");
eventInfo.setDoesNotMatchTaskSpecification();
eventInfo.record(task);
return;
}
if (isProtected((PrismObject<ShadowType>) currentShadow)) {
if (StringUtils.isNotBlank(synchronizationPolicy.getIntent())) {
List<PropertyDelta<?>> modifications = SynchronizationUtils.createSynchronizationTimestampsDelta(currentShadow);
PropertyDelta<String> intentDelta = PropertyDelta.createModificationReplaceProperty(ShadowType.F_INTENT, currentShadow.getDefinition(), synchronizationPolicy.getIntent());
modifications.add(intentDelta);
try {
repositoryService.modifyObject(ShadowType.class, currentShadow.getOid(), modifications, subResult);
task.recordObjectActionExecuted(currentShadow, ChangeType.MODIFY, null);
} catch (Throwable t) {
task.recordObjectActionExecuted(currentShadow, ChangeType.MODIFY, t);
} finally {
task.markObjectActionExecutedBoundary();
}
}
subResult.recordSuccess();
eventInfo.record(task);
LOGGER.debug("SYNCHRONIZATION: DONE (dry run) for protected shadow {}", currentShadow);
return;
}
Class<? extends FocusType> focusType = determineFocusClass(synchronizationPolicy, resourceType);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Synchronization is enabled, focus class: {}, found applicable policy: {}", focusType, Utils.getPolicyDesc(synchronizationPolicy));
}
SynchronizationSituation situation = determineSituation(focusType, change, synchronizationPolicy, configuration.asObjectable(), task, subResult);
if (logDebug) {
LOGGER.debug("SYNCHRONIZATION: SITUATION: '{}', currentOwner={}, correlatedOwner={}", situation.getSituation().value(), situation.getCurrentOwner(), situation.getCorrelatedOwner());
} else {
LOGGER.trace("SYNCHRONIZATION: SITUATION: '{}', currentOwner={}, correlatedOwner={}", situation.getSituation().value(), situation.getCurrentOwner(), situation.getCorrelatedOwner());
}
eventInfo.setOriginalSituation(situation.getSituation());
// overwritten
eventInfo.setNewSituation(situation.getSituation());
if (change.isUnrelatedChange() || Utils.isDryRun(task)) {
PrismObject object = null;
if (change.getCurrentShadow() != null) {
object = change.getCurrentShadow();
} else if (change.getOldShadow() != null) {
object = change.getOldShadow();
}
Collection modifications = SynchronizationUtils.createSynchronizationSituationAndDescriptionDelta(object, situation.getSituation(), task.getChannel(), false);
if (StringUtils.isNotBlank(synchronizationPolicy.getIntent())) {
modifications.add(PropertyDelta.createModificationReplaceProperty(ShadowType.F_INTENT, object.getDefinition(), synchronizationPolicy.getIntent()));
}
try {
repositoryService.modifyObject(ShadowType.class, object.getOid(), modifications, subResult);
task.recordObjectActionExecuted(object, ChangeType.MODIFY, null);
} catch (Throwable t) {
task.recordObjectActionExecuted(object, ChangeType.MODIFY, t);
} finally {
task.markObjectActionExecutedBoundary();
}
subResult.recordSuccess();
eventInfo.record(task);
LOGGER.debug("SYNCHRONIZATION: DONE (dry run/unrelated) for {}", object);
return;
}
// must be here, because when the reaction has no action, the
// situation will be not set.
PrismObject<ShadowType> newCurrentShadow = saveSyncMetadata((PrismObject<ShadowType>) currentShadow, situation, change, synchronizationPolicy, task, parentResult);
if (newCurrentShadow != null) {
change.setCurrentShadow(newCurrentShadow);
}
SynchronizationSituationType newSituation = reactToChange(focusType, change, synchronizationPolicy, situation, resourceType, logDebug, configuration, task, subResult);
eventInfo.setNewSituation(newSituation);
eventInfo.record(task);
subResult.computeStatus();
} catch (SystemException ex) {
// avoid unnecessary re-wrap
eventInfo.setException(ex);
eventInfo.record(task);
subResult.recordFatalError(ex);
throw ex;
} catch (Exception ex) {
eventInfo.setException(ex);
eventInfo.record(task);
subResult.recordFatalError(ex);
throw new SystemException(ex);
} finally {
task.markObjectActionExecutedBoundary();
// if (LOGGER.isTraceEnabled()) {
// LOGGER.trace(subResult.dump());
// }
}
LOGGER.debug("SYNCHRONIZATION: DONE for {}", currentShadow);
}
use of com.evolveum.midpoint.util.exception.SystemException in project midpoint by Evolveum.
the class FocusMainPanel method createTabPanel.
protected WebMarkupContainer createTabPanel(String panelId, FormSpecificationType formSpecificationType, PageAdminObjectDetails<F> parentPage) {
String panelClassName = formSpecificationType.getPanelClass();
Class<?> panelClass;
try {
panelClass = Class.forName(panelClassName);
} catch (ClassNotFoundException e) {
throw new SystemException("Panel class '" + panelClassName + "' as specified in admin GUI configuration was not found", e);
}
if (AbstractFocusTabPanel.class.isAssignableFrom(panelClass)) {
Constructor<?> constructor;
try {
constructor = panelClass.getConstructor(String.class, Form.class, LoadableModel.class, LoadableModel.class, LoadableModel.class, PageBase.class);
} catch (NoSuchMethodException | SecurityException e) {
throw new SystemException("Unable to locate constructor (String,Form,LoadableModel,LoadableModel,LoadableModel,PageBase) in " + panelClass + ": " + e.getMessage(), e);
}
AbstractFocusTabPanel<F> tabPanel;
try {
tabPanel = (AbstractFocusTabPanel<F>) constructor.newInstance(panelId, getMainForm(), getObjectModel(), assignmentsModel, projectionModel, parentPage);
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new SystemException("Error instantiating " + panelClass + ": " + e.getMessage(), e);
}
return tabPanel;
} else if (AbstractObjectTabPanel.class.isAssignableFrom(panelClass)) {
Constructor<?> constructor;
try {
constructor = panelClass.getConstructor(String.class, Form.class, LoadableModel.class, PageBase.class);
} catch (NoSuchMethodException | SecurityException e) {
throw new SystemException("Unable to locate constructor (String,Form,LoadableModel,PageBase) in " + panelClass + ": " + e.getMessage(), e);
}
AbstractObjectTabPanel<F> tabPanel;
try {
tabPanel = (AbstractObjectTabPanel<F>) constructor.newInstance(panelId, getMainForm(), getObjectModel(), parentPage);
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new SystemException("Error instantiating " + panelClass + ": " + e.getMessage(), e);
}
return tabPanel;
} else {
throw new UnsupportedOperationException("Tab panels that are not subclasses of AbstractObjectTabPanel or AbstractFocusTabPanel are not supported yet (got " + panelClass + ")");
}
}
use of com.evolveum.midpoint.util.exception.SystemException in project midpoint by Evolveum.
the class AuditEventRecordProvider method internalSize.
protected int internalSize() {
String query = generateFullQuery(AUDIT_RECORDS_QUERY_COUNT + auditEventQuery, false, true);
long count;
try {
count = getAuditService().countObjects(query, parameters, new OperationResult("internalSize"));
} catch (SecurityViolationException | SchemaException e) {
// TODO: proper error handling (MID-3536)
throw new SystemException(e.getMessage(), e);
}
int providerSize = ((Long) count).intValue();
return !exportSize ? providerSize : (providerSize < MAX_EXPORT_ROWS_COUNT ? providerSize : MAX_EXPORT_ROWS_COUNT);
}
use of com.evolveum.midpoint.util.exception.SystemException in project midpoint by Evolveum.
the class BeanUnmarshaller method unmarshalProtectedByteArray.
private ProtectedByteArrayType unmarshalProtectedByteArray(PrimitiveXNode<String> prim, Class beanClass, ParsingContext pc) throws SchemaException {
ProtectedByteArrayType protectedType = new ProtectedByteArrayType();
String stringValue = prim.getParsedValue(DOMUtil.XSD_STRING, String.class);
if (stringValue == null) {
return null;
}
try {
protectedType.setClearValue(ArrayUtils.toObject(stringValue.getBytes("UTF-8")));
} catch (UnsupportedEncodingException e) {
throw new SystemException("UTF-8 encoding is not supported", e);
}
return protectedType;
}
use of com.evolveum.midpoint.util.exception.SystemException in project midpoint by Evolveum.
the class BeanUnmarshaller method unmarshalEntry.
/**
* Parses either a map entry, or a fictitious heterogeneous list property.
*
* It makes sure that a 'key' property is inserted into 'bean' object, being sourced from 'node' structure.
* Node itself can be single-valued or multi-valued, corresponding to single or multi-valued 'key' property.
* ---
* A notable (and quite ugly) exception is processing of fictitious heterogeneous lists.
* In this case we have a ListXNode that should be interpreted as a MapXNode, inserting fictitious property
* named after abstract multivalued property in the parent bean.
*
* For example, when we have (embedded in ExecuteScriptType):
* {
* pipeline: *[
* { element: search, ... },
* { element: sequence, ... }
* ]
* }
*
* ...it should be, in fact, read as if it would be:
*
* {
* pipeline: {
* scriptingExpression: [
* { type: SearchExpressionType, ... },
* { type: ExpressionSequenceType, ... }
* ]
* }
* }
*
* (The only difference is in element names, which are missing in the latter snippet, but let's ignore that here.)
*
* Fictitious heterogeneous list entry here is "scriptingExpression", a property of pipeline (ExpressionPipelineType).
*
* We have to create the following data structure (corresponding to latter snippet):
*
* instance of ExecuteScriptType:
* scriptingExpression = instance of JAXBElement(pipeline, ExpressionPipelineType): [1]
* scriptingExpression = List of [2]
* - JAXBElement(search, SearchExpressionType)
* - JAXBElement(sequence, ExpressionSequenceType)
*
* We in fact invoke this method twice with the same node (a two-entry list, marked as '*' in the first snippet):
* 1) bean=ExecuteScriptType, key=pipeline, node=HList(*), isHeteroListProperty=false
* 2) bean=ExpressionPipelineType, key=scriptingExpression, node=HList(*), isHeteroListProperty=true <<<
*
* During the first call we fill in scriptingExpression (single value) in ExecuteScriptType [1]; during the second one
* we fill in scriptingExpression (multivalued) in ExpressionPipelineType [2].
*
* Now let's expand the sample.
*
* This XNode tree:
* {
* pipeline: *[
* { element: search, type: RoleType, searchFilter: {...}, action: log },
* { element: sequence, value: **[
* { element: action, type: delete },
* { element: action, type: assign, parameter: {...} },
* { element: search, type: UserType }
* ] }
* ]
* }
*
* Should be interpreted as:
* {
* pipeline: {
* scriptingExpression: [
* { type: SearchExpressionType, type: RoleType, searchFilter: {...}, action: log }
* { type: ExpressionSequenceType, scriptingExpression: [
* { type: ActionExpressionType, type: delete },
* { type: ActionExpressionType, type: assign, parameter: {...} },
* { type: SearchExpressionType, type: UserType }
* ] }
* ]
* }
* }
*
* Producing the following data:
*
* instance of ExecuteScriptType:
* scriptingExpression = instance of JAXBElement(pipeline, ExpressionPipelineType): [1]
* scriptingExpression = List of [2]
* - JAXBElement(search, instance of SearchExpressionType):
* type: RoleType,
* searchFilter: (...),
* action: log,
* - JAXBElement(sequence, instance of ExpressionSequenceType):
* scriptingExpression = List of
* - JAXBElement(action, instance of ActionExpressionType):
* type: delete
* - JAXBElement(action, instance of ActionExpressionType):
* type: assign
* parameter: (...),
* - JAXBElement(search, instance of SearchExpressionType):
* type: UserType
*
* Invocations of this method will be:
* 1) bean=ExecuteScriptType, key=pipeline, node=HList(*), isHeteroListProperty=false
* 2) bean=ExpressionPipelineType, key=scriptingExpression, node=HList(*), isHeteroListProperty=true <<<
* 3) bean=SearchExpressionType, key=type, node='type: c:RoleType', isHeteroListProperty=false
* 4) bean=SearchExpressionType, key=searchFilter, node=XNode(map:1 entries), isHeteroListProperty=false
* 5) bean=SearchExpressionType, key=action, node=XNode(map:1 entries), isHeteroListProperty=false
* 6) bean=ActionExpressionType, key=type, node='type: log', isHeteroListProperty=false
* 7) bean=ExpressionSequenceType, key=scriptingExpression, node=HList(**), isHeteroListProperty=true <<<
* 8) bean=ActionExpressionType, key=type, node='type: delete', isHeteroListProperty=false
* 9) bean=ActionExpressionType, key=type, node='type: assign', isHeteroListProperty=false
* 10) bean=ActionExpressionType, key=parameter, node=XNode(map:2 entries), isHeteroListProperty=false
* 11) bean=ActionParameterValueType, key=name, node='name: role', isHeteroListProperty=false
* 12) bean=ActionParameterValueType, key=value, node='value: rome555c-7797-11e2-94a6-001e8c717e5b', isHeteroListProperty=false
* 13) bean=SearchExpressionType, key=type, node='type: UserType', isHeteroListProperty=false
*
* Here we have 2 calls with isHeteroListProperty=true; first for pipeline.scriptingExpression, second for
* sequence.scriptingExpression.
*/
private <T> void unmarshalEntry(@NotNull T bean, @NotNull Class<T> beanClass, @NotNull QName key, @NotNull XNode node, @NotNull XNode containingNode, boolean isHeteroListProperty, @NotNull ParsingContext pc) throws SchemaException {
//System.out.println("bean=" + bean.getClass().getSimpleName() + ", key=" + key.getLocalPart() + ", node=" + node + ", isHeteroListProperty=" + isHeteroListProperty);
final String propName = key.getLocalPart();
// this code is just to keep this method reasonably short
PropertyAccessMechanism mechanism = new PropertyAccessMechanism();
if (!mechanism.compute(bean, beanClass, propName, key, node, pc)) {
return;
}
final String actualPropertyName = mechanism.actualPropertyName;
final boolean storeAsRawType = mechanism.storeAsRawType;
final Method getter = mechanism.getter;
final Method setter = mechanism.setter;
final boolean wrapInJaxbElement = mechanism.wrapInJaxbElement;
if (Element.class.isAssignableFrom(mechanism.paramType)) {
throw new IllegalArgumentException("DOM not supported in field " + actualPropertyName + " in " + beanClass);
}
// The type T that is expected by the bean, i.e. either by
// - setMethod(T value), or
// - Collection<T> getMethod()
// We use it to retrieve the correct value when parsing the node.
// We might specialize it using the information derived from the node (to deal with inclusive polymorphism,
// i.e. storing ExclusionPolicyConstraintType where AbstractPolicyConstraintType is expected).
@NotNull Class<?> paramType;
if (!storeAsRawType && !isHeteroListProperty) {
Class<?> t = specializeParamType(node, mechanism.paramType, pc);
if (t == null) {
// indicates a problem
return;
} else {
paramType = t;
}
} else {
paramType = mechanism.paramType;
}
if (!(node instanceof ListXNode) && Object.class.equals(paramType) && !storeAsRawType) {
throw new IllegalArgumentException("Object property (without @Raw) not supported in field " + actualPropertyName + " in " + beanClass);
}
// String paramNamespace = inspector.determineNamespace(paramType);
boolean problem = false;
Object propValue = null;
Collection<Object> propValues = null;
// (instead of list) and process it as a single value. Only when
if (node instanceof ListXNode && (!node.isHeterogeneousList() || isHeteroListProperty)) {
ListXNode xlist = (ListXNode) node;
if (setter != null) {
try {
Object value = unmarshalSinglePropValue(node, actualPropertyName, paramType, storeAsRawType, beanClass, pc);
if (wrapInJaxbElement) {
propValue = wrapInJaxbElement(value, mechanism.objectFactory, mechanism.elementFactoryMethod, propName, beanClass, pc);
} else {
propValue = value;
}
} catch (SchemaException e) {
problem = processSchemaException(e, node, pc);
}
} else {
// No setter, we have to use collection getter
propValues = new ArrayList<>(xlist.size());
for (XNode xsubsubnode : xlist) {
try {
Object valueToAdd;
Object value = unmarshalSinglePropValue(xsubsubnode, actualPropertyName, paramType, storeAsRawType, beanClass, pc);
if (value != null) {
if (isHeteroListProperty) {
QName elementName = xsubsubnode.getElementName();
if (elementName == null) {
// TODO better error handling
throw new SchemaException("Heterogeneous list with a no-elementName node: " + xsubsubnode);
}
Class valueClass = value.getClass();
QName jaxbElementName;
if (QNameUtil.hasNamespace(elementName)) {
jaxbElementName = elementName;
} else {
// Approximate solution: find element in schema registry - check for type compatibility
// in order to exclude accidental name matches (like c:expression/s:expression).
Optional<ItemDefinition> itemDefOpt = getSchemaRegistry().findItemDefinitionsByElementName(elementName).stream().filter(def -> getSchemaRegistry().findTypeDefinitionsByType(def.getTypeName()).stream().anyMatch(typeDef -> typeDef.getCompileTimeClass() != null && typeDef.getCompileTimeClass().isAssignableFrom(valueClass))).findFirst();
if (itemDefOpt.isPresent()) {
jaxbElementName = itemDefOpt.get().getName();
} else {
LOGGER.warn("Heterogeneous list member with unknown element name '" + elementName + "': " + value);
// unqualified
jaxbElementName = elementName;
}
}
@SuppressWarnings("unchecked") JAXBElement jaxbElement = new JAXBElement<>(jaxbElementName, valueClass, value);
valueToAdd = jaxbElement;
} else {
if (wrapInJaxbElement) {
valueToAdd = wrapInJaxbElement(value, mechanism.objectFactory, mechanism.elementFactoryMethod, propName, beanClass, pc);
} else {
valueToAdd = value;
}
}
propValues.add(valueToAdd);
}
} catch (SchemaException e) {
problem = processSchemaException(e, xsubsubnode, pc);
}
}
}
} else {
try {
propValue = unmarshalSinglePropValue(node, actualPropertyName, paramType, storeAsRawType, beanClass, pc);
if (wrapInJaxbElement) {
propValue = wrapInJaxbElement(propValue, mechanism.objectFactory, mechanism.elementFactoryMethod, propName, beanClass, pc);
}
} catch (SchemaException e) {
problem = processSchemaException(e, node, pc);
}
}
if (setter != null) {
try {
setter.invoke(bean, propValue);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new SystemException("Cannot invoke setter " + setter + " on bean of type " + beanClass + ": " + e.getMessage(), e);
}
} else if (getter != null) {
Object getterReturn;
Collection<Object> col;
try {
getterReturn = getter.invoke(bean);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new SystemException("Cannot invoke getter " + getter + " on bean of type " + beanClass + ": " + e.getMessage(), e);
}
try {
col = (Collection<Object>) getterReturn;
} catch (ClassCastException e) {
throw new SystemException("Getter " + getter + " on bean of type " + beanClass + " returned " + getterReturn + " instead of collection");
}
if (propValue != null) {
col.add(propValue);
} else if (propValues != null) {
for (Object propVal : propValues) {
col.add(propVal);
}
} else if (!problem) {
throw new IllegalStateException("Strange. Multival property " + propName + " in " + beanClass + " produced null values list, parsed from " + containingNode);
}
if (!isHeteroListProperty) {
checkJaxbElementConsistence(col, pc);
}
} else {
throw new IllegalStateException("Uh? No setter nor getter.");
}
}
Aggregations