Package com.impetus.labs.korus.core

Source Code of com.impetus.labs.korus.core.KorusRuntime

/*******************************************************************************
* Korus - http://code.google.com/p/korus
* Copyright (C) 2010 Impetus Technologies, Inc.(http://www.impetus.com)
* This file is part of Korus.
* Korus is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as published
* by the Free Software Foundation (http://www.gnu.org/licenses/gpl.html)
* Korus is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with Korus.  If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package com.impetus.labs.korus.core;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Properties;

import com.impetus.labs.korus.core.executer.Executer;
import com.impetus.labs.korus.core.executer.RequestExecuter;
import com.impetus.labs.korus.core.message.Message;
import com.impetus.labs.korus.core.message.RawMessage;
import com.impetus.labs.korus.core.message.SerializableMessage;
import com.impetus.labs.korus.core.process.BaseProcess;
import com.impetus.labs.korus.core.process.Process;
import com.impetus.labs.korus.core.scheduler.RequestScheduler;
import com.impetus.labs.korus.core.scheduler.Scheduler;
import com.impetus.labs.korus.exception.KorusException;
import com.impetus.labs.korus.exception.ProcessAlreadyExistsException;
import com.impetus.labs.korus.util.StringUtil;
/**
* KorusRuntime is used to initialize Korus Runtime which includes initializing
* Executers, Schedulers and also managing communication between Processes and
* Nodes.
*/
public class KorusRuntime
{
  private static final int JAVA_PORT = 7935;

  private static final int ERLANG_PORT = 7936;

  private static boolean isWebRequest = false;

  private static boolean isDistributed = false;

  private static int numberOfRequestExecuters = 0;

  private static int numberOfRequestSchedulers = 0;

  private static int numberOfCoreSchedulers = 1;

  private static int numberOfCoreExecuters = 0;

  private static int numberOfCPUCores = 0;

  private static Hashtable<String, BaseProcess> registeredProcessCollection = new Hashtable<String, BaseProcess>();

  private static Executer[] coreExecuterList = null;

  private static Scheduler[] coreSchedulerList = null;

  private static RequestExecuter[] requestExecuterList = null;

  private static RequestScheduler[] requestSchedulerList = null;

  private static int index = 0;

  private static HashMap<String, BufferedWriter> connectedNodesMap = new HashMap<String, BufferedWriter>();

  static
  {
    // Determine no. of cores and start coreExecuters
    numberOfCPUCores = Runtime.getRuntime().availableProcessors();

    numberOfCoreExecuters = numberOfCPUCores;

    try
    {
      readPropertiesFile();
    } catch (Exception e)
    {

      e.printStackTrace();
    }

    // Start the Core Executers/Schedulers
    coreExecuterList = new Executer[numberOfCoreExecuters];
    for (int i = 0; i < coreExecuterList.length; i++)
    {
      coreExecuterList[i] = new Executer();
      coreExecuterList[i].start();
    }

    coreSchedulerList = new Scheduler[numberOfCoreSchedulers];
    for (int i = 0; i < coreSchedulerList.length; i++)
    {
      coreSchedulerList[i] = new Scheduler();
      coreSchedulerList[i].start();
    }

    // Web request scenario handling
    if (isWebRequest)
    {

      // Start the newRequest Executers/Schedulers
      requestExecuterList = new RequestExecuter[numberOfRequestExecuters];
      for (int i = 0; i < requestExecuterList.length; i++)
      {
        requestExecuterList[i] = new RequestExecuter();
        requestExecuterList[i].start();
      }

      requestSchedulerList = new RequestScheduler[numberOfRequestSchedulers];
      for (int i = 0; i < requestSchedulerList.length; i++)
      {
        requestSchedulerList[i] = new RequestScheduler();
        requestSchedulerList[i].start();
      }
    }

    // InterNode Interaction and Cross Language Compatibility
    if (isDistributed)
    {
      // Start KourusReader Thread
      Runnable korusReader = new KorusReader();
      Thread korusReaderThread = new Thread(korusReader);
      korusReaderThread.start();

      // Start KorusWriter Thread
      Runnable korusWriter = new KorusWriter();
      Thread korusWriterThread = new Thread(korusWriter);
      korusWriterThread.start();

    }
  }

  /**
   * Get the next executer from the coreExecuterList.
   *
   * @return the executer from the coreExecuterList.
   */
  public static Executer getNextExecuter()
  {
    Executer executer = coreExecuterList[index % numberOfCoreExecuters];
    index++;
    return executer;
  }

  /**
   * Get the next scheduler from the coreSchedulerList.
   *
   * @return the scheduler from the coreSchedulerList.
   */
  public static Scheduler getNextCoreScheduler()
  {
    Scheduler scheduler = coreSchedulerList[index % numberOfCoreSchedulers];
    index++;
    return scheduler;
  }

  /**
   * Get the next requestExecuter from the requestExecuterList.
   *
   * @return the next requestExecuter from the requestExecuterList.
   */
  public static RequestExecuter getNextRequestExecuter()
  {
    RequestExecuter requestExecuter = requestExecuterList[index
        % numberOfRequestExecuters];
    index++;
    return requestExecuter;
  }

  /**
   * Get the next requestScheduler from the requestSchedulerList.
   *
   * @return the next requestScheduler from the requestSchedulerList.
   */
  public static RequestScheduler getNextRequestScheduler()
  {
    RequestScheduler requestScheduler = requestSchedulerList[index
        % numberOfRequestSchedulers];
    index++;
    return requestScheduler;
  }

  /**
   * Send message to a registered process.
   *
   * @param processName
   *            Name of the process by which it is registered in the
   *            registeredProcessMap.
   * @param message
   *            Message to be passed to the process contains ('KEY','VALUE')
   *            pairs.
   */
  public synchronized static void send(String processName, Message message)
  {

    // 1. Select process from registered process list
    BaseProcess process = getRegisteredProcess(processName);
    if (process == null)
    {
      System.out.println("Message sent to an unregistered Process: "
          + processName);
    } else
    {
      // 2. Put message in process's messageQueue
      process.putMessage(message);
      // 3. Put this Process in Scheduler's processQueue
      Scheduler.setProcess(process);
    }

  }

  /**
   * Send message to a registered process.
   *
   * @param processName
   *            Name of the process by which it is registered in the
   *            registeredProcessMap.
   * @param message
   *            Message to be passed to the process contains ('KEY','VALUE')
   *            pairs.
   * @param isFirst
   *            isFirst to identify the first part of request and give
   *            priority over other sub-parts.
   */
  public synchronized static void send(String processName, Message message,
      boolean isFirst)
  {

    // 1. Select process from registered process list
    BaseProcess process = getRegisteredProcess(processName);
    if (process == null)
    {
      System.out.println("Message sent to an unregistered Process: "
          + processName);
    } else
    {
      // 2. Put message in process's messageQueue
      process.putMessage(message);
      if (isFirst)
      {
        // 3. Put this Process in Scheduler's processQueue
        RequestScheduler.setProcess(process);
      } else
        Scheduler.setProcess(process);
    }

  }

  /**
   * Send message to a process using(processID).
   *
   * @param process
   *            process to which message to be sent.
   * @param message
   *            Message to be passed to the process contains ('KEY','VALUE')
   *            pairs.
   */
  public static void send(Process process, Message message)
  {
    // 1. Put message in process's messageQueue
    process.putMessage(message);
    // 2. Put this Process in Schedulers processQueue
    Scheduler.setProcess(process);
  }

  /**
   * Method to send the message to remoteNode process to execute the part of
   * the request.
   *
   * @param nodeName
   *            to which request to be sent
   * @param processName
   *            process name of the remote node to be called
   * @param message
   *            Message containing the parameters for the process
   */
  public static void send(String nodeName, String processName, Message message)
  {
    send(nodeName, processName, message, JAVA_PORT);
  }

  /**
   * Method to send response data to erlangNode
   *
   * @param nodeName
   *            The name of the node from which a request to process has been
   *            sent to Korus
   * @param processName
   *            Name of the process at erlang node which will collect the
   *            response
   * @param message
   *            Message containing the parameters for the process
   */
  public static void sendToErlang(String nodeName, String processName,
      Message message)
  {
    send(nodeName, processName, message, ERLANG_PORT);
  }

  /**
   * Send data to the node.
   *
   * @param nodeName
   *            The name of the node from which a request to process has been
   *            sent to Korus
   * @param processName
   *            Name of the process at erlang node which will collect the
   *            response
   * @param rawMessage
   *            Message containing the parameters for the process
   * @param port
   *            Port to connect with.
   */
  public static void send(String nodeName, String processName,
      RawMessage rawMessage, int port)
  {
    if (isDistributed)
    {
      if (connectedNodesMap.get(nodeName) == null)
      {
        connect(nodeName, port);
      }
      rawMessage.put("action", processName);
      String request = StringUtil.messageToString(rawMessage);
      SerializableMessage message = new SerializableMessage(nodeName,
          request);
      KorusWriter.setRequestMessage(message);
    } else
    {
      System.out
          .println("KorusRuntime is not initalized in DISTRIBUTED_MODE to enable it, set DISTRIBUTED_MODE=true in properties file");
    }
  }

  /**
   * Get the Process from registeredProcessMap if registered.
   *
   * @param processName
   *            Name of the process by which it is registered in the
   *            registeredProcessMap.
   * @return the Process from registeredProcessMap if registered else returns
   *         null.
   */
  public static BaseProcess getRegisteredProcess(String processName)
  {
    return registeredProcessCollection.get(processName);
  }

  /**
   * Register the Process with unique name in the registeredProcessMap.
   *
   * @param processName
   *            processName a unique name of the process by which the process
   *            to be register in the registeredProcessMap.
   * @param process
   *            The process which is to be registered with a unique name.
   * @throws ProcessAlreadyExistsException
   */
  public static void registerProcess(String processName, BaseProcess process)
      throws ProcessAlreadyExistsException
  {
    if (registeredProcessCollection.get(processName) == null)
      registeredProcessCollection.put(processName, process);
    else
      throw new ProcessAlreadyExistsException(processName);

  }

  /**
   * Method to connect to the given ipAddress and put the bufferedWriter in
   * the Hashmap to reuse the connection.
   *
   * @param ipAddress
   *            ipAddress of the remoteNode
   * @param port
   *            port to be used for connection.
   */
  private static void connect(String ipAddress, int port)
  {
    BufferedWriter bufferedWriter = null;
    Socket clientSocket = null;
    try
    {
      // connect to the Socket
      clientSocket = new Socket(ipAddress, port);
      bufferedWriter = new BufferedWriter(new OutputStreamWriter(
          clientSocket.getOutputStream()));
      connectedNodesMap.put(ipAddress, bufferedWriter);
    } catch (UnknownHostException e)
    {
      e.printStackTrace();
    } catch (IOException e)
    {
      e.printStackTrace();
    }

  }

  /**
   * Get the connectedNodesMap
   *
   * @return A Hashmap containing the bufferedWriter of connected nodes.
   */
  public static HashMap<String, BufferedWriter> getConnectedNodesMap()
  {
    return connectedNodesMap;
  }

  /**
   * @return the JAVA_PORT
   */
  public static int getJavaPort()
  {
    return JAVA_PORT;
  }

  /**
   * @return the ERLANG_PORT
   */
  public static int getErlangPort()
  {
    return ERLANG_PORT;
  }

  /**
   * Method to read the properties file to initialize the configuration
   * parameters.
   *
   * @throws KorusException
   */

  public static void readPropertiesFile() throws KorusException
  {
    try
    {
      String korusHome = System.getenv("KORUS_HOME");

      File propertiesFile = new File(korusHome
          + "/properties/korus.properties");

      Properties properties = new Properties();
      FileInputStream fileInputStream = new FileInputStream(
          propertiesFile);
      properties.load(fileInputStream);

      // check if DISTRIBUTED_MODE is 'true'
      // else initialize with false
      if (properties.containsKey("DISTRIBUTED_MODE"))
      {
        isDistributed = Boolean.parseBoolean(properties
            .getProperty("DISTRIBUTED_MODE"));
      } else
      {
        keyNotFound("DISTRIBUTED_MODE");
      }

      // Check for Kind of request if WEB_REQUEST='true'
      // and if KEYS not found or incorrect initialization
      // Initialize the advance processing parameters with default value 1

      if (properties.containsKey("WEB_REQUEST"))
      {
        isWebRequest = Boolean.parseBoolean(properties
            .getProperty("WEB_REQUEST"));
        if (isWebRequest)
        {
          if (properties.containsKey("NUMBER_OF_REQUEST_EXECUTERS"))
          {
            numberOfRequestExecuters = Integer.parseInt(properties
                .getProperty("NUMBER_OF_REQUEST_EXECUTERS"));
            if (numberOfRequestExecuters <= 0)
            {
              numberOfRequestExecuters = 1;
              System.out
                  .println("The value of parameter NUMBER_OF_REQUEST_EXECUTERS in properties file must be greater than 0\n"
                      + "setting it to default value 1");
            }
          } else
          {

            keyNotFound("NUMBER_OF_REQUEST_EXECUTERS");
          }
          if (properties.containsKey("NUMBER_OF_REQUEST_SCHEDULERS"))
          {
            numberOfRequestSchedulers = Integer.parseInt(properties
                .getProperty("NUMBER_OF_REQUEST_SCHEDULERS"));
            if (numberOfRequestSchedulers <= 0)
            {
              numberOfRequestSchedulers = 1;
              System.out
                  .println("The value of parameter NUMBER_OF_REQUEST_SCHEDULERS in properties file must be greater than 0\n"
                      + "setting it to default value 1");
            }
          } else
          {
            keyNotFound("NUMBER_OF_REQUEST_SCHEDULERS");
          }
        }
      } else
      {
        keyNotFound("WEB_REQUEST");
      }
      // Check for NUMBER_OF_CORE_SCHEDULERS if not found or incorrect
      // initialization start with default value 1.

      if (properties.containsKey("NUMBER_OF_CORE_SCHEDULERS"))
      {
        numberOfCoreSchedulers = Integer.parseInt(properties
            .getProperty("NUMBER_OF_CORE_SCHEDULERS"));

        if (numberOfCoreSchedulers <= 0)
        {
          numberOfCoreSchedulers = 1;
          System.out
              .println("The value of parameter NUMBER_OF_CORE_SCHEDULERS in properties file must be greater than 0\n"
                  + "setting it to default value 1");
        }
      } else
      {
        keyNotFound("NUMBER_OF_CORE_SCHEDULERS");
      }
      // Check for NUMBER_OF_CORE_EXECUTERS if not found or incorrect
      // initialization start with default value equals to the number Of
      // CPUCores

      if (properties.containsKey("NUMBER_OF_CORE_EXECUTERS"))
      {
        numberOfCoreExecuters = Integer.parseInt(properties
            .getProperty("NUMBER_OF_CORE_EXECUTERS"));
        if (numberOfCoreExecuters <= 0)
        {
          numberOfCoreExecuters = numberOfCPUCores;
          System.out
              .println("The value of parameter NUMBER_OF_CORE_EXECUTERS in properties file must be greater than 0\n"
                  + "setting it to default value equals to the number Of CPUCores");

        }
      } else
      {
        keyNotFound("NUMBER_OF_CORE_EXECUTERS");
      }

    }

    catch (NumberFormatException e)
    {
      throw new KorusException(
          "Properties File Format error!\nDefine parameters(Case-sensitive) in (KEY=VALUE)format where KEY is a 'String' and VALUE is an 'integer'");
    }

    catch (IOException e)
    {
      System.out
          .println("Properties File not found!\nStarting with default configuration");
    }
    System.out.println("Korus Runtime parameters");
    System.out.println("WEB_REQUEST Mode: " + isWebRequest);
    System.out.println("DISTRIBUTED Mode: " + isDistributed);
    System.out.println("NUMBER_OF_CORE_SCHEDULERS: "
        + numberOfCoreSchedulers);
    System.out
        .println("NUMBER_OF_CORE_EXECUTERS: " + numberOfCoreExecuters);
    System.out.println("NUMBER_OF_REQUEST_EXECUTERS: "
        + numberOfRequestExecuters);
    System.out.println("NUMBER_OF_REQUEST_SCHEDULERS: "
        + numberOfRequestSchedulers);

  }

  /**
   * To load the static KorusRuntime
   */
  public static void load()
  {
    // load the static block
  }

  public static void keyNotFound(String key)
  {
    System.out
        .println("Key: "
            + key
            + " is not defined in the PropertiesFile \nInitializing with default configuration.");
  }

  public static boolean getExecutionMode()
  {
      return isWebRequest;
  }

}
TOP

Related Classes of com.impetus.labs.korus.core.KorusRuntime

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.