org.apache.james.task.TaskExecutionDetails.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of james-server-task-api
Show all versions of james-server-task-api
Defines the TaskManager API allow to manage James' long running jobs
/** **************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you 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 org.apache.james.task
import java.time.{Instant, ZonedDateTime}
import java.util.{Objects, Optional}
import com.google.common.base.MoreObjects
import org.apache.james.task.TaskExecutionDetails.AdditionalInformation
import org.apache.james.task.TaskManager.Status._
object TaskExecutionDetails {
trait AdditionalInformation {
def timestamp: Instant
}
def from(task: Task, id: TaskId, hostname: Hostname) = new TaskExecutionDetails(id, task.`type`, WAITING, submittedDate = ZonedDateTime.now, submittedNode = hostname, () => task.details)
}
class TaskExecutionDetails(val taskId: TaskId,
private val `type`: TaskType,
private val status: TaskManager.Status,
private val submittedDate: ZonedDateTime,
private val submittedNode: Hostname,
private val additionalInformation: () => Optional[TaskExecutionDetails.AdditionalInformation],
private val startedDate: Optional[ZonedDateTime] = Optional.empty(),
private val ranNode: Optional[Hostname] = Optional.empty(),
private val completedDate: Optional[ZonedDateTime] = Optional.empty(),
private val canceledDate: Optional[ZonedDateTime] = Optional.empty(),
private val cancelRequestedNode: Optional[Hostname] = Optional.empty(),
private val failedDate: Optional[ZonedDateTime] = Optional.empty()) {
def getTaskId: TaskId = taskId
def getType: TaskType = `type`
def getStatus: TaskManager.Status = status
def getAdditionalInformation: Optional[TaskExecutionDetails.AdditionalInformation] = additionalInformation()
def getSubmittedDate: ZonedDateTime = submittedDate
def getSubmittedNode: Hostname = submittedNode
def getStartedDate: Optional[ZonedDateTime] = startedDate
def getRanNode: Optional[Hostname] = ranNode
def getCompletedDate: Optional[ZonedDateTime] = completedDate
def getCanceledDate: Optional[ZonedDateTime] = canceledDate
def getCancelRequestedNode: Optional[Hostname] = cancelRequestedNode
def getFailedDate: Optional[ZonedDateTime] = failedDate
def started(hostname: Hostname): TaskExecutionDetails = status match {
case WAITING => start(hostname)
case _ => this
}
def completed(finalAdditionalInformation: Optional[AdditionalInformation]): TaskExecutionDetails = status match {
case IN_PROGRESS => complete(finalAdditionalInformation)
case CANCEL_REQUESTED => complete(finalAdditionalInformation)
case WAITING => complete(finalAdditionalInformation)
case _ => this
}
def failed(finalAdditionalInformation: Optional[AdditionalInformation]): TaskExecutionDetails = status match {
case IN_PROGRESS => fail(finalAdditionalInformation)
case CANCEL_REQUESTED => fail(finalAdditionalInformation)
case _ => this
}
def cancelRequested(hostname: Hostname): TaskExecutionDetails = status match {
case IN_PROGRESS => requestCancel(hostname)
case WAITING => requestCancel(hostname)
case _ => this
}
def cancelEffectively(finalAdditionalInformation: Optional[AdditionalInformation]): TaskExecutionDetails = status match {
case CANCEL_REQUESTED => cancel(finalAdditionalInformation)
case IN_PROGRESS => cancel(finalAdditionalInformation)
case WAITING => cancel(finalAdditionalInformation)
case _ => this
}
def updateInformation(information: AdditionalInformation): TaskExecutionDetails = status match {
case IN_PROGRESS => update(information)
case CANCEL_REQUESTED => update(information)
case _ => this
}
def canEqual(other: Any): Boolean = other.isInstanceOf[TaskExecutionDetails]
override def equals(other: Any): Boolean = other match {
case that: TaskExecutionDetails =>
(that canEqual this) &&
Objects.equals(taskId, that.taskId) &&
Objects.equals(`type`, that.`type`) &&
Objects.equals(additionalInformation(), that.additionalInformation()) &&
Objects.equals(status, that.status) &&
Objects.equals(submittedDate, that.submittedDate) &&
Objects.equals(submittedNode, that.submittedNode) &&
Objects.equals(startedDate, that.startedDate) &&
Objects.equals(ranNode, that.ranNode) &&
Objects.equals(completedDate, that.completedDate) &&
Objects.equals(canceledDate, that.canceledDate) &&
Objects.equals(cancelRequestedNode, that.cancelRequestedNode) &&
Objects.equals(failedDate, that.failedDate)
case _ => false
}
override def hashCode(): Int =
Objects.hash(taskId, `type`, additionalInformation(), status, submittedDate, submittedNode, startedDate, ranNode, completedDate, canceledDate, cancelRequestedNode, failedDate)
override def toString: String =
MoreObjects.toStringHelper(this)
.add("taskId", taskId)
.add("type", `type`)
.add("additionalInformation", additionalInformation())
.add("status", status)
.add("submittedDate", submittedDate)
.add("submittedNode", submittedNode)
.add("startedDate", startedDate)
.add("ranNode", ranNode)
.add("completedDate", completedDate)
.add("canceledDate", canceledDate)
.add("cancelRequestedNode", cancelRequestedNode)
.add("failedDate", failedDate)
.toString
private def start(hostname: Hostname) = new TaskExecutionDetails(taskId, `type`, IN_PROGRESS,
submittedDate = submittedDate,
submittedNode = submittedNode,
additionalInformation = additionalInformation,
startedDate = Optional.of(ZonedDateTime.now),
ranNode = Optional.of(hostname))
private def complete(finalAdditionalInformation: Optional[AdditionalInformation]) = new TaskExecutionDetails(taskId, `type`, TaskManager.Status.COMPLETED,
submittedDate = submittedDate,
submittedNode = submittedNode,
additionalInformation = () => finalAdditionalInformation,
startedDate = startedDate,
ranNode = ranNode,
cancelRequestedNode = cancelRequestedNode,
completedDate = Optional.of(ZonedDateTime.now))
private def fail(finalAdditionalInformation: Optional[AdditionalInformation]) = new TaskExecutionDetails(taskId, `type`, TaskManager.Status.FAILED,
submittedDate = submittedDate,
submittedNode = submittedNode,
additionalInformation = () => finalAdditionalInformation,
startedDate = startedDate,
ranNode = ranNode,
cancelRequestedNode = cancelRequestedNode,
failedDate = Optional.of(ZonedDateTime.now))
private def requestCancel(hostname: Hostname) = new TaskExecutionDetails(taskId, `type`, TaskManager.Status.CANCEL_REQUESTED,
submittedDate = submittedDate,
submittedNode = submittedNode,
additionalInformation = additionalInformation,
startedDate = startedDate,
ranNode = ranNode,
cancelRequestedNode = Optional.of(hostname),
canceledDate = Optional.of(ZonedDateTime.now))
private def update(updatedInformation: AdditionalInformation) = new TaskExecutionDetails(taskId, `type`, status,
submittedDate = submittedDate,
submittedNode = submittedNode,
additionalInformation = () => Optional.of(updatedInformation),
startedDate = startedDate,
ranNode = ranNode,
cancelRequestedNode = cancelRequestedNode,
canceledDate = canceledDate)
private def cancel(finalAdditionalInformation: Optional[AdditionalInformation]) = new TaskExecutionDetails(taskId, `type`, TaskManager.Status.CANCELLED,
submittedDate = submittedDate,
submittedNode = submittedNode,
additionalInformation = () => finalAdditionalInformation,
startedDate = startedDate,
ranNode = ranNode,
cancelRequestedNode = cancelRequestedNode,
canceledDate = Optional.of(ZonedDateTime.now))
}