Skip to content

Commit

Permalink
Implemented MID-3188: Notify by e-mail when error occured to speed up…
Browse files Browse the repository at this point in the history
… reaction in production
  • Loading branch information
mederly committed Jun 21, 2016
1 parent 08bf2c7 commit 202a8cf
Show file tree
Hide file tree
Showing 6 changed files with 384 additions and 0 deletions.
Expand Up @@ -442,6 +442,13 @@
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="simpleTaskNotifier" type="tns:SimpleTaskNotifierType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>
TODO
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="generalNotifier" type="tns:GeneralNotifierType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>
Expand Down Expand Up @@ -525,6 +532,13 @@
</xsd:appinfo>
</xsd:annotation>
</xsd:enumeration>
<xsd:enumeration value="taskEvent">
<xsd:annotation>
<xsd:appinfo>
<jaxb:typesafeEnumMember name="TASK_EVENT"/>
</xsd:appinfo>
</xsd:annotation>
</xsd:enumeration>
</xsd:restriction>
</xsd:simpleType>

Expand Down Expand Up @@ -796,6 +810,19 @@
</xsd:complexContent>
</xsd:complexType>

<xsd:complexType name="SimpleTaskNotifierType">
<xsd:annotation>
<xsd:documentation>
TODO
</xsd:documentation>
</xsd:annotation>
<xsd:complexContent>
<xsd:extension base="tns:GeneralNotifierType">
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>


<xsd:complexType name="DummyNotifierType">
<xsd:annotation>
<xsd:documentation>
Expand Down
@@ -0,0 +1,138 @@
/*
* Copyright (c) 2010-2016 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.notifications.api.events;

import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.schema.result.OperationResultStatus;
import com.evolveum.midpoint.task.api.LightweightIdentifierGenerator;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.task.api.TaskRunResult;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
* @author mederly
*/
public class TaskEvent extends BaseEvent {

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

@NotNull private final Task task;
@Nullable private final TaskRunResult taskRunResult; // nullable only if operationType == ADD
@NotNull private final EventOperationType operationType; // only ADD or DELETE

public TaskEvent(LightweightIdentifierGenerator lightweightIdentifierGenerator, @NotNull Task task, @Nullable TaskRunResult runResult,
@NotNull EventOperationType operationType, String channel) {
super(lightweightIdentifierGenerator);
this.task = task;
this.taskRunResult = runResult;
this.operationType = operationType;
setChannel(channel);
}

@NotNull
public Task getTask() {
return task;
}

@Nullable
public TaskRunResult getTaskRunResult() {
return taskRunResult;
}

@NotNull
public EventOperationType getOperationType() {
return operationType;
}

public boolean isTemporaryError() {
return taskRunResult != null && taskRunResult.getRunResultStatus() == TaskRunResult.TaskRunResultStatus.TEMPORARY_ERROR;
}

public boolean isPermanentError() {
return taskRunResult != null && taskRunResult.getRunResultStatus() == TaskRunResult.TaskRunResultStatus.PERMANENT_ERROR;
}

public boolean isFinished() {
return taskRunResult != null &&
(taskRunResult.getRunResultStatus() == TaskRunResult.TaskRunResultStatus.FINISHED ||
taskRunResult.getRunResultStatus() == TaskRunResult.TaskRunResultStatus.FINISHED_HANDLER);
}

public boolean isInterrupted() {
return taskRunResult != null && taskRunResult.getRunResultStatus() == TaskRunResult.TaskRunResultStatus.INTERRUPTED;
}

public boolean isRestartRequested() {
return taskRunResult != null && taskRunResult.getRunResultStatus() == TaskRunResult.TaskRunResultStatus.RESTART_REQUESTED;
}

@Override
public boolean isStatusType(EventStatusType eventStatusType) {
if (eventStatusType == null) {
return false;
}
if (taskRunResult == null) {
return eventStatusType == EventStatusType.SUCCESS || eventStatusType == EventStatusType.ALSO_SUCCESS || eventStatusType == EventStatusType.IN_PROGRESS;
}
OperationResult result = taskRunResult.getOperationResult();
switch (eventStatusType) {
case SUCCESS:
case ALSO_SUCCESS: return result.isSuccess() || result.isHandledError() || result.isWarning();
case IN_PROGRESS: return false;
case FAILURE: return result.isError();
case ONLY_FAILURE: return result.isFatalError();
default: throw new IllegalStateException("Invalid eventStatusType: " + eventStatusType);
}
}

@Override
public boolean isOperationType(EventOperationType eventOperationType) {
return this.operationType == eventOperationType;
}

@Override
public boolean isCategoryType(EventCategoryType eventCategoryType) {
return eventCategoryType == EventCategoryType.TASK_EVENT;
}

@Override
public boolean isRelatedToItem(ItemPath itemPath) {
return false;
}

@Override
public boolean isUserRelated() {
return false;
}

public OperationResultStatus getOperationResultStatus() {
return taskRunResult != null && taskRunResult.getOperationResult() != null ? taskRunResult.getOperationResult().getStatus() : null;
}

public String getMessage() {
return taskRunResult != null && taskRunResult.getOperationResult() != null ? taskRunResult.getOperationResult().getMessage() : null;
}

public long getProgress() {
return taskRunResult != null ? taskRunResult.getProgress() : task.getProgress();
}
}
@@ -0,0 +1,94 @@
/*
* Copyright (c) 2010-2016 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.notifications.impl;

import com.evolveum.midpoint.notifications.api.NotificationManager;
import com.evolveum.midpoint.notifications.api.events.TaskEvent;
import com.evolveum.midpoint.task.api.*;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.xml.ns._public.common.common_3.EventOperationType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
* One of interfaces of the notifier to midPoint.
*
* Used to catch task-related events.
*
* @author mederly
*/
@Component
public class NotificationTaskListener implements TaskListener {

private static final Trace LOGGER = TraceManager.getTrace(NotificationTaskListener.class);
private static final String OPERATION_PROCESS_EVENT = NotificationTaskListener.class.getName() + "." + "processEvent";

@Autowired
private LightweightIdentifierGenerator lightweightIdentifierGenerator;

@Autowired
private NotificationManager notificationManager;

@Autowired
private NotificationsUtil notificationsUtil;

@Autowired
private TaskManager taskManager;

@PostConstruct
public void init() {
taskManager.registerTaskListener(this);
LOGGER.trace("Task listener registered.");
}

@Override
public void onTaskStart(Task task) {
createAndProcessEvent(task, null, EventOperationType.ADD);
}

@Override
public void onTaskFinish(Task task, TaskRunResult runResult) {
createAndProcessEvent(task, runResult, EventOperationType.DELETE);
}

private void createAndProcessEvent(Task task, TaskRunResult runResult, EventOperationType operationType) {
TaskEvent event = new TaskEvent(lightweightIdentifierGenerator, task, runResult, operationType, task.getChannel());

if (task.getOwner() != null) {
event.setRequester(new SimpleObjectRefImpl(notificationsUtil, task.getOwner().asObjectable()));
event.setRequestee(new SimpleObjectRefImpl(notificationsUtil, task.getOwner().asObjectable()));
} else {
LOGGER.debug("No owner for task " + task + ", therefore no requester and requestee will be set for event " + event.getId());
}

Task opTask = taskManager.createTaskInstance(OPERATION_PROCESS_EVENT);
notificationManager.processEvent(event, opTask, opTask.getResult());
}

@Override
public void onTaskThreadStart(Task task, boolean isRecovering) {
// not implemented
}

@Override
public void onTaskThreadFinish(Task task) {
// not implemented
}
}
Expand Up @@ -26,6 +26,7 @@
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.schema.util.ObjectTypeUtil;
import com.evolveum.midpoint.schema.util.ShadowUtil;
import com.evolveum.midpoint.util.exception.CommonException;
import com.evolveum.midpoint.util.exception.ObjectNotFoundException;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.util.exception.SystemException;
Expand Down Expand Up @@ -77,6 +78,16 @@ public static String getResourceNameFromRepo(RepositoryService repositoryService
}
}

public String getObjectName(String oid, OperationResult result) {
try {
PrismObject<? extends ObjectType> object = cacheRepositoryService.getObject(ObjectType.class, oid, null, result);
return PolyString.getOrig(object.asObjectable().getName());
} catch (CommonException|RuntimeException e) {
LoggingUtils.logUnexpectedException(LOGGER, "Couldn't get resource", e);
return null;
}
}

public ObjectType getObjectType(SimpleObjectRef simpleObjectRef, boolean allowNotFound, OperationResult result) {
if (simpleObjectRef == null) {
return null;
Expand Down
Expand Up @@ -137,6 +137,7 @@ public boolean processEvent(Event event, EventHandlerType eventHandlerType, Noti
shouldContinue = shouldContinue && processNotifiers(event, eventHandlerType.getSimpleCampaignNotifier(), notificationManager, task, result);
shouldContinue = shouldContinue && processNotifiers(event, eventHandlerType.getSimpleCampaignStageNotifier(), notificationManager, task, result);
shouldContinue = shouldContinue && processNotifiers(event, eventHandlerType.getSimpleReviewerNotifier(), notificationManager, task, result);
shouldContinue = shouldContinue && processNotifiers(event, eventHandlerType.getSimpleTaskNotifier(), notificationManager, task, result);

logEnd(LOGGER, event, eventHandlerType, shouldContinue);
return shouldContinue;
Expand Down

0 comments on commit 202a8cf

Please sign in to comment.