Package com.catify.processengine.core.nodes.eventdefinition

Source Code of com.catify.processengine.core.nodes.eventdefinition.TimerEventDefinition

/**
* *******************************************************
* Copyright (C) 2013 catify <info@catify.com>
* *******************************************************
*
* 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.catify.processengine.core.nodes.eventdefinition;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import javax.annotation.PostConstruct;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.beans.factory.annotation.Value;

import scala.concurrent.duration.Duration;
import akka.actor.ActorRef;

import com.catify.processengine.core.data.dataobjects.TimerBean;
import com.catify.processengine.core.data.dataobjects.TimerSPI;
import com.catify.processengine.core.messages.ActivationMessage;
import com.catify.processengine.core.messages.CommitMessage;
import com.catify.processengine.core.messages.DeactivationMessage;
import com.catify.processengine.core.messages.TriggerMessage;
import com.catify.processengine.core.util.TimerUtil;

/**
* The TimerEventDefinition will constantly evaluate the due timers and create {@link TriggerMessage}s to fire those.
* Saving and loading is handled via the configured {@link TimerSPI} service provider, while time calculations are done
* via the {@link TimerUtil}.
*
* @author christopher köster
* @author claus straube
*
*/
@Configurable
public class TimerEventDefinition extends EventDefinition {
 
  static final Logger LOG = LoggerFactory
      .getLogger(TimerEventDefinition.class);
 
  /** The timer spi implementation id set in the spring context. */
  @Value("${timer.implementation}")
  private String timerServiceProviderId;
 
  /** The timer polling interval in milliseconds. */
  @Value("${timer.interval}")
  private long timerPollingInterval;
 
  /** The event that is holding this event definition. */
  private ActorRef eventActorRef;
 
  private TimerTypes timerType;
  private String isoDate;
 
  private TimerSPI timerSPI;

  /**
   * Instantiates a new timer event definition.
   *
   * @param eventNodeActorRef the underlying event node actor ref
   * @param timerType the timer type
   * @param isoDate the iso date
   */
  public TimerEventDefinition(ActorRef eventNodeActorRef, TimerTypes timerType, String isoDate) {
    this.timerType = timerType;
    this.isoDate = isoDate;
    this.eventActorRef = eventNodeActorRef;
  }
 
  /**
   * Inits the spring dependent fields, like TimerSPI service provider and the akka scheduler.
   */
  @PostConstruct
  void initSpringDependentFields() {
    this.timerSPI = TimerSPI.getTimerImpl(timerServiceProviderId);
   
    // register cycle timers
    if (timerType == TimerTypes.TIMECYCLE) {
      List<Long> timeToFire = this.getTimeToFire();
      this.saveTimers(timeToFire);
    }
   
    // init akka scheduler
    actorSystem.scheduler().schedule(
        Duration.create(10000, TimeUnit.MILLISECONDS), // delay until scheduler starts
        Duration.create(timerPollingInterval, TimeUnit.MILLISECONDS), // polling interval
        new Runnable() {
          @Override
          public void run() {
            // for each due timer create a trigger message and send it to the underlying event node
            List<TimerBean> dueTimers = timerSPI.loadDueTimers(getSelf().toString());
            for (TimerBean timerBean : dueTimers) {
              eventActorRef.tell(new TriggerMessage(timerBean.getProcessInstanceId(), null), getSender());
            }
          }
        },
        actorSystem.dispatcher());
  }
 
  /* (non-Javadoc)
   * @see com.catify.processengine.core.nodes.eventdefinition.EventDefinition#acitivate(com.catify.processengine.core.messages.ActivationMessage)
   */
  @Override
  protected CommitMessage<?> activate(ActivationMessage message) {

    // create and save next timer
    String processInstanceId = message.getProcessInstanceId();
    List<Long> timeToFire = this.getTimeToFire();
   
    this.saveTimers(processInstanceId, timeToFire);
   
    return createSuccessfullCommitMessage(message.getProcessInstanceId());
  }

  /* (non-Javadoc)
   * @see com.catify.processengine.core.nodes.eventdefinition.EventDefinition#deactivate(com.catify.processengine.core.messages.DeactivationMessage)
   */
  @Override
  protected CommitMessage<?> deactivate(DeactivationMessage message) {
   
    this.timerSPI.deleteTimer(this.getSelf().toString(), message.getProcessInstanceId());
   
    return createSuccessfullCommitMessage(message.getProcessInstanceId());
  }
  /* (non-Javadoc)
   * @see com.catify.processengine.core.nodes.eventdefinition.EventDefinition#trigger(com.catify.processengine.core.messages.TriggerMessage)
   */
  @Override
  protected CommitMessage<?> trigger(TriggerMessage message) {   
    // if this timer is unbounded set next timer
    if (timerType == TimerTypes.TIMECYCLE && TimerUtil.isUnboundedCycle(isoDate)) {
      List<Long> timeToFire = this.getTimeToFire();
      this.saveTimers(message.getProcessInstanceId(), timeToFire);
    }
   
    return createSuccessfullCommitMessage(message.getProcessInstanceId());
  }

  /**
   * Save timers.
   *
   * @param processInstanceId the process instance id
   * @param timeToFire the list of time to fire
   */
  private void saveTimers(String processInstanceId, List<Long> timeToFire) {
    for (Long longToFire : timeToFire) {
      this.timerSPI.saveTimer(new TimerBean(longToFire, this.getSelf().toString(), processInstanceId));
    }
  }
 
  /**
   * Save timers (with generated process instance id).
   *
   * @param timeToFire the time to fire
   */
  private void saveTimers(List<Long> timeToFire) {
    for (Long longToFire : timeToFire) {
      this.timerSPI.saveTimer(new TimerBean(longToFire, this.getSelf().toString(), UUID.randomUUID().toString()));
    }
  }

  /**
   * Gets the time to fire depending on the TimerTypes.
   *
   * @return the time to fire
   */
  private List<Long> getTimeToFire() {
    List<Long> timeToFire = new ArrayList<Long>();
   
    switch (this.timerType) {
    case TIMEDATE:
      timeToFire.add(TimerUtil.calculateTimeToFireForDate(this.isoDate));
      break;
    case TIMEDURATION:
      timeToFire.add(TimerUtil.calculateTimeToFireForDuration(this.isoDate));
      break;
    case TIMECYCLE:
      timeToFire.addAll(TimerUtil.calculateTimeToFireForCycle(this.isoDate));
      break;
    default:
      LOG.error("Unrecognized Timer type. TimerEventDefinition will fail!");
      break;
    }
    return timeToFire;
  }

}
TOP

Related Classes of com.catify.processengine.core.nodes.eventdefinition.TimerEventDefinition

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.