/*
 * Copyright 2008 GigaSpaces Technologies Ltd. All rights reserved.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY AND 
 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. GIGASPACES WILL NOT 
 * BE LIABLE FOR ANY DAMAGE OR LOSS IN CONNECTION WITH THE SOFTWARE.
 */

package com.gigaspaces.examples.tutorials.queries.feeder;

import org.openspaces.core.GigaSpace;
import org.openspaces.core.context.GigaSpaceContext;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

import com.gigaspaces.examples.tutorials.queries.common.OrderEvent;

import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

/**
 * A feeder bean that starts a scheduled task that writes a new OrderEvent object to the space.
 * The orderEvent type attribute is set randomly to "normal" or "Insecure". <p>
 * 
 * The space is injected into this bean using OpenSpaces support for @GigaSpaceContext
 * annotation. <p>
 * 
 * The scheduled support uses the java.util.concurrent Scheduled Executor Service. It
 * is started and stopped based on Spring life-cycle events.
 */
public class OrderEventFeeder implements InitializingBean, DisposableBean {

	private Random randomGen = new Random();
	
    private ScheduledExecutorService executorService;

    //	Delayed result bearing action
    private ScheduledFuture<?> sf;
    
    /**
     * Delay between scheduled tasks
     */
    private long defaultDelay = 1000;
    
    /**
     * The scheduled orderEvent feeding task.
     */ 
    private OrderEventFeederTask orderEventFeederTask;
    
    @GigaSpaceContext(name = "gigaSpace")
    private GigaSpace gigaSpace;
    
    public void setGigaSpace(GigaSpace gigaSpace) {
		this.gigaSpace = gigaSpace;
	}
    
    /**
     * Unique ID for this client
     */
    private Double feederID;
    
    /**
     * @param defaultDelay - Sets default delay between feeding tasks.
     */
    public void setDefaultDelay(long defaultDelay) {
        this.defaultDelay = defaultDelay;
    }
    
	/**
	 * The first method to run upon bean Initialization, when implementing InitializingBean.
	 * Runs init() method which starts a scheduled orderEvent feeding task. 
	 */
	public void afterPropertiesSet() throws Exception {
		init();
    }
	
	/**
	 * init - Starts a scheduled orderEvent feeding task.
	 * @throws Exception
	 */
	public void init() throws Exception {
    	
		//	Create unique ID for this feeder
		feederID = new Double(System.nanoTime()); 
		
		System.out.println("Feeder ["+feederID.toString()+"], Starting order feeding cycles (Delay between cycles "+defaultDelay+" msec)");
        
		//	Create a thread pool containing 1 thread capable of performing scheduled tasks
        executorService = Executors.newScheduledThreadPool(1);
        
        orderEventFeederTask = new OrderEventFeederTask();
        
        //	Schedule the thread to execute the task at fixed rate with the default delay defined 
        sf = executorService.scheduleAtFixedRate(
        										orderEventFeederTask	// The task to schedule
        										,defaultDelay 			// Initial Delay before starting
        										,defaultDelay			// Delay between tasks
        										,TimeUnit.MILLISECONDS	// Time unit for the delay
        										);
    }
	
    public void destroy() throws Exception {
    	//	Shutting down the thread pool upon bean disposal
    	sf.cancel(true);
        sf = null;
        executorService.shutdown();
    }

    public class OrderEventFeederTask implements Runnable {
    	
    	//	Counts number of fed orderEvents
        private int counter;

    	Integer randomizedNameSuffix;
    	String randomizedType;
    	
        public void run() {
            try { 
            	
            	//	Prepare randomized values to set the orderEvent attributes with
            	randomizedNameSuffix = randomGen.nextInt(99)+1;
            	if (randomGen.nextBoolean()) {
            		randomizedType=OrderEvent.TYPE_NORMAL;
            	}
            	else {
            		randomizedType=OrderEvent.TYPE_INSECURE;
            	}
            	
            	//	Create a new orderEvent with randomized attributes
            	OrderEvent orderEvent = new OrderEvent("FN" + randomizedNameSuffix /* firstName */
            											,"LN" + randomizedNameSuffix/* lastName */
            											,feederID.toString() /* feederID */
            											,randomizedType /* type */
            											,randomGen.nextInt(99)+1 /* riskInvolvedFactor */
            											,(randomGen.nextInt(19)+1)*100); /* price */
            	            	
                //	Write the new orderEvent to the space
            	gigaSpace.write(orderEvent);
                System.out.println("\nFeeder wrote order:\n"+orderEvent);
            } 
            catch (Exception e) {
                e.printStackTrace();
            }
        }

        public int getCounter() {
            return counter;
        }
    }

    public int getFeedCount() {
        return orderEventFeederTask.getCounter();
    }

	public void setFeederID(Double feederID) {
		this.feederID = feederID;
	}

	public Double getFeederID() {
		return feederID;
	}
}
GigaSpaces.com - Legal Notice - 3rd Party Licenses - Site Map - API Docs - Forum - Downloads - Blog - White Papers - Contact Tech Writing - Gen. by Atlassian Confluence