blob: 1a4bbbb455c7e8554f1bb04a3b848282dafee3e4 [file] [log] [blame]
/** **************************************************************
* 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.eventsourcing
import java.util
import org.apache.james.eventsourcing.eventstore.History
import org.apache.james.eventsourcing.{Event, EventId}
import org.apache.james.task.Task.Result
import org.apache.james.task.TaskExecutionDetails.AdditionalInformation
import org.apache.james.task.TaskManager.Status
import org.apache.james.task.{Hostname, Task}
import scala.collection.JavaConverters._
class TaskAggregate private(val aggregateId: TaskAggregateId, private val history: History) {
history.getEvents.asScala.headOption match {
case Some(Created(_, _, _, _)) =>
case _ => throw new IllegalArgumentException("History must start with Created event")
}
private val currentStatus: Status = history
.getEvents
.asScala
.foldLeft(DecisionProjection.empty)((decision, event) => decision.update(event))
.status
.get
private def optionToJavaList[T](element: Option[T]): util.List[T] = element.toList.asJava
private def createEventIfNotFinished(event: EventId => Event): Option[Event] = {
if (!currentStatus.isFinished) {
Some(event(history.getNextEventId))
} else
None
}
private def createEvent(event: EventId => Event): Option[Event] = Some(event(history.getNextEventId))
private def createEventIfNotFinishedAsJavaList(event: EventId => Event): util.List[Event] = optionToJavaList(createEventIfNotFinished(event))
private[eventsourcing] def start(hostname: Hostname): util.List[Event] =
createEventIfNotFinishedAsJavaList(Started(aggregateId, _, hostname))
private[eventsourcing] def requestCancel(hostname: Hostname): util.List[Event] =
createEventIfNotFinishedAsJavaList(CancelRequested(aggregateId, _, hostname))
private[eventsourcing] def update(additionalInformation: AdditionalInformation): util.List[Event] =
(currentStatus match {
case Status.IN_PROGRESS => createEvent(AdditionalInformationUpdated(aggregateId, _, additionalInformation))
case Status.CANCEL_REQUESTED => createEvent(AdditionalInformationUpdated(aggregateId, _, additionalInformation))
case _ => None
}).toList.asJava
private[eventsourcing] def complete(result: Result, additionalInformation: Option[AdditionalInformation]): util.List[Event] =
createEventIfNotFinishedAsJavaList(Completed(aggregateId, _, result, additionalInformation))
private[eventsourcing] def fail(additionalInformation: Option[AdditionalInformation], errorMessage: Option[String], exception: Option[String]): util.List[Event] =
createEventIfNotFinishedAsJavaList(Failed(aggregateId, _, additionalInformation, errorMessage, exception))
private[eventsourcing] def cancel(additionalInformation: Option[AdditionalInformation]): util.List[Event] =
createEventIfNotFinishedAsJavaList(Cancelled(aggregateId, _, additionalInformation))
}
object TaskAggregate {
def fromHistory(aggregateId: TaskAggregateId, history: History): TaskAggregate = new TaskAggregate(aggregateId, history)
def create(aggregateId: TaskAggregateId, task: Task, hostname: Hostname): util.List[Event] = {
List[Event](Created(aggregateId, EventId.first(), task, hostname)).asJava
}
}