Skip to content

Commit

Permalink
Clean up notifications code a little bit
Browse files Browse the repository at this point in the history
Preparing for MID-5849 and MID-5350 resolution.
  • Loading branch information
mederly committed Mar 12, 2020
1 parent e5df24f commit 9849faa
Show file tree
Hide file tree
Showing 39 changed files with 1,268 additions and 1,445 deletions.
Expand Up @@ -1043,6 +1043,10 @@ public void recordNotApplicableIfUnknown() {
}
}

public void recordNotApplicable() {
recordStatus(OperationResultStatus.NOT_APPLICABLE, (String) null);
}

public boolean isMinor() {
return importance == MINOR;
}
Expand Down
Expand Up @@ -126,6 +126,8 @@ public void test100ModifyUserAddAccount() throws Exception {

XMLGregorianCalendar startTime = clock.currentTimeXMLGregorianCalendar();

setGlobalTracingOverride(createModelLoggingTracingProfile());

// WHEN
when();
modifyUserAddAccount(USER_JACK_OID, ACCOUNT_JACK_DUMMY_FILE, task, result);
Expand Down Expand Up @@ -206,6 +208,9 @@ public void test100ModifyUserAddAccount() throws Exception {

@Test
public void test119ModifyUserDeleteAccount() throws Exception {

unsetGlobalTracingOverride();

// GIVEN
Task task = createPlainTask();
OperationResult result = task.getResult();
Expand Down
Expand Up @@ -13,13 +13,20 @@
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.xml.ns._public.common.common_3.EventHandlerType;

/**
* @author mederly
*/
@FunctionalInterface
public interface EventHandler {
public interface EventHandler<E extends Event, C extends EventHandlerType> {

/**
* @return true if we should continue with processing, false otherwise
*/
boolean processEvent(E event, C eventHandlerType, Task task, OperationResult result) throws SchemaException;

/**
* @return Type of events this handler is capable of handling.
*/
Class<E> getEventType();

// true if we should continue with processing, false otherwise
boolean processEvent(Event event, EventHandlerType eventHandlerType, NotificationManager notificationManager,
Task task, OperationResult result) throws SchemaException;
/**
* @return Type of configuration objects for this event handler. The handler is selected based on exact match of this type.
*/
Class<C> getEventHandlerConfigurationType();
}
Expand Up @@ -13,21 +13,20 @@
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.xml.ns._public.common.common_3.EventHandlerType;

import org.jetbrains.annotations.NotNull;

/**
* @author mederly
* Handles notification events.
*/

public interface NotificationManager {

void registerTransport(String name, Transport transport);
Transport getTransport(String name);

// event may be null
void processEvent(Event event, Task task, OperationResult result);
void processEvent(@NotNull Event event, Task task, OperationResult result);


boolean processEvent(Event event, EventHandlerType eventHandlerType, Task task, OperationResult result);
boolean processEvent(@NotNull Event event, EventHandlerType eventHandlerBean, Task task, OperationResult result);

boolean isDisabled();

void setDisabled(boolean disabled);
}
Expand Up @@ -51,11 +51,6 @@ public boolean isCategoryType(EventCategoryType eventCategoryType) {
EventCategoryType.CERT_CASE_EVENT.equals(eventCategoryType);
}

@Deprecated // obsolete name
public Collection<AccessCertificationCaseType> getCasesAwaitingResponseFromRequestee() {
return getCasesAwaitingResponseFromActualReviewer();
}

public Collection<AccessCertificationCaseType> getCasesAwaitingResponseFromActualReviewer() {
List<AccessCertificationCaseType> rv = new ArrayList<>();
for (AccessCertificationCaseType aCase : cases) {
Expand Down
Expand Up @@ -26,6 +26,7 @@
import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;

import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
Expand Down Expand Up @@ -148,6 +149,7 @@ private void executeNotifyAny(OperationStatus status, ResourceOperationDescripti
notificationManager.processEvent(request, task, result);
}

@NotNull
private ResourceObjectEvent createRequest(OperationStatus status,
ResourceOperationDescription operationDescription,
Task task,
Expand Down
@@ -0,0 +1,52 @@
/*
* Copyright (c) 2020 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.notifications.impl;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.springframework.stereotype.Component;

import com.evolveum.midpoint.notifications.api.EventHandler;
import com.evolveum.midpoint.notifications.api.events.Event;
import com.evolveum.midpoint.schema.result.OperationResult;
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 com.evolveum.midpoint.xml.ns._public.common.common_3.EventHandlerType;

/**
*
*/
@Component
public class EventHandlerRegistry {

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

private Map<Class<? extends EventHandlerType>, EventHandler<?, ?>> handlers = new ConcurrentHashMap<>();

public <C extends EventHandlerType, E extends Event> void registerEventHandler(Class<C> configType, EventHandler<E, C> handler) {
LOGGER.trace("Registering event handler {} for config type {}", handler, configType);
handlers.put(configType, handler);
}

public boolean forwardToHandler(Event event, EventHandlerType configuration, Task task, OperationResult result) throws SchemaException {
EventHandler<?, ?> handler = handlers.get(configuration.getClass());
if (handler == null) {
throw new IllegalStateException("Unknown handler for " + configuration);
} else if (!handler.getEventType().isAssignableFrom(event.getClass())) {
LOGGER.trace("Not forwarding event {} to handler {} because the handler does not support events of that type",
event, handler);
return true;
} else {
//noinspection unchecked,rawtypes
return ((EventHandler) handler).processEvent(event, configuration, task, result);
}
}
}
Expand Up @@ -51,6 +51,8 @@ public class NotificationHook implements ChangeHook {

private static final String HOOK_URI = SchemaConstants.NS_MODEL + "/notification-hook-3";

private static final String OP_INVOKE = NotificationHook.class.getName() + ".invoke";

@Autowired private LightweightIdentifierGenerator lightweightIdentifierGenerator;
@Autowired private HookRegistry hookRegistry;
@Autowired private NotificationManager notificationManager;
Expand All @@ -59,36 +61,37 @@ public class NotificationHook implements ChangeHook {
@PostConstruct
public void init() {
hookRegistry.registerChangeHook(HOOK_URI, this);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Notifier change hook registered.");
}
LOGGER.trace("Notifier change hook registered.");
}

@Override
public HookOperationMode invoke(@NotNull ModelContext context, @NotNull Task task, @NotNull OperationResult result) {

// todo in the future we should perhaps act in POSTEXECUTION state, but currently the clockwork skips this state
if (context.getState() != ModelState.FINAL) {
return HookOperationMode.FOREGROUND;
}
if (notificationManager.isDisabled()) {
LOGGER.trace("Notifications are temporarily disabled, exiting the hook.");
return HookOperationMode.FOREGROUND;
}
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Notification change hook called with model context: " + context.debugDump());
}
if (context.getFocusContext() == null) {
if (LOGGER.isTraceEnabled()) {
public <O extends ObjectType> HookOperationMode invoke(@NotNull ModelContext<O> context, @NotNull Task task,
@NotNull OperationResult parentResult) {
OperationResult result = parentResult.createSubresult(OP_INVOKE);
try {
if (context.getState() != ModelState.FINAL) {
return HookOperationMode.FOREGROUND;
}
if (notificationManager.isDisabled()) {
LOGGER.trace("Notifications are temporarily disabled, exiting the hook.");
return HookOperationMode.FOREGROUND;
}
LOGGER.trace("Notification change hook called with model context:\n{}", context.debugDumpLazily());
if (context.getFocusContext() == null) {
LOGGER.trace("Focus context is null, exiting the hook.");
return HookOperationMode.FOREGROUND;
}
return HookOperationMode.FOREGROUND;
}

emitModelEvent(context, task, result);
emitPolicyRulesEvents(context, task, result);
emitModelEvent(context, task, result);
emitPolicyRulesEvents(context, task, result);

return HookOperationMode.FOREGROUND;
return HookOperationMode.FOREGROUND;
} catch (Throwable t) {
result.recordFatalError(t);
throw t;
} finally {
result.computeStatusIfUnknown();
}
}

private void emitPolicyRulesEvents(ModelContext<?> context, Task task, OperationResult result) {
Expand Down

0 comments on commit 9849faa

Please sign in to comment.