package com.fitbank.uci.calendar; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.StringTokenizer; import com.fitbank.uci.client.ToDo; import com.fitbank.uci.client.UCILogger; import com.fitbank.uci.common.UCIException; import com.fitbank.uci.server.Controlador; import com.fitbank.uci.server.mail.ErrorEvent; import com.fitbank.uci.server.manager.DeviceEventTypes; import com.fitbank.uci.server.manager.ParameterDetail; /** * Clase que implementa el proceso de consumo de los mensajes recibidos en * UCI * * @author Fit-Bank */ public class UCITask extends Controlador { /** * Campo utilizado para controlar la ejecución de la tarea. * * @since empty */ boolean service = false; /** * Campo utilizado para para indicar si el Controlador se encuentra bajo proceso de Shutdown * * @since empty */ boolean shutdown = false; /** * Campo utilizado para el acceso a los logs * * @since empty */ private UCILogger logger; /** * Campo utilizado para manejar la referencia a la clase que se debe ejecutar por la tarea * * @since empty */ @SuppressWarnings("unchecked") private Class todoClass; /** * Tiempo de espera para la ejecución de la Tarea * * @since empty */ private Integer iTimer; /** * Campo utilizado para indicar si las ejecuciones de las tareas deben hacerlo en paralelo * * @since empty */ private boolean paralell = false; /** * Descripción de la Tarea * * @since empty */ private String taskDescription; /** * Parametros para la tarea * * @since empty */ private String taskParameters; /** * Campo utilizado para almacenar la hora de la última ejecución. * * @since empty */ private String lastExecution = ""; /** * Parametro Clase * * @since empty */ public final static String TODO_CLASS = "TODO_CLASS"; /** * Parametro tiempo * * @since empty */ public final static String TIMER = "TIMER"; /** * Parámetro descripción * * @since empty */ public final static String DESCRIPTION = "DESCRIPTION"; /** * Parámetro paralelo. * * @since empty */ public final static String PARALELL = "PARALELL"; /** * Parametro contenedor de los parámetros para la Tarea. * * @since empty */ public final static String PARAMETERS = "PARAMETERS"; /** * Crea una nueva instancia de UCITask * * @since empty * @throws Exception Error */ public UCITask() throws Exception { logger = UCILogger.getInstance(); } /** * Fija un nuevo valor del atributo LastExecution * * @param lastExecution Nuevo valor de LastExecution * @since empty */ public void setLastExecution(String lastExecution) { this.lastExecution = lastExecution; } /** * Método que Permite fjar los parámetros de ejecución del Conector * * @param pParameters Valor de los parámetros del Conector * @since empty * @throws Exception Error */ @SuppressWarnings("unchecked") public void setParameters(String pParameters) throws Exception { this.addMessage("Iniciada la Tarea", DeviceEventTypes.INIT); service = true; Map param = (Map) this.parseParametes(pParameters); this.todoClass = Class.forName(param.get(TODO_CLASS).getValue()); try { @SuppressWarnings("unused") ToDo td = (ToDo) this.todoClass.newInstance(); } catch (ClassCastException e) { throw new UCIException("TASK000", "La clase " + this.todoClass.getName() + " no implementa ToDo"); } this.iTimer = Integer.parseInt(param.get(TIMER).getValue()); this.taskDescription = param.get(DESCRIPTION).getValue(); this.taskParameters = this.name + "," + param.get(PARAMETERS).getValue(); if (param.size() > 3) { this.paralell = Boolean.parseBoolean(param.get(PARALELL).getValue()); } start(); } /** * Obtiene el valor de LastExecution * * @return El valor de LastExecution * @since empty */ public String getLastExecution() { return lastExecution; } //~ Métodos //************************************************************************************** /** * Método que indica si el controlador se encuentra o no conectado * * @return Entrega el indicador * @since empty * @throws Exception Error */ public boolean isConnected() throws Exception { return service; } /** * Método que entrega la descripción del conector * * @return Entrega la descripción del conector * @since empty * @throws Exception Error */ public String getDescription() throws Exception { return "Tarea Calendarizada " + this.taskDescription; } /** * Método que entrga un indicador de si el Proceso de consumo de Mensajes se * encuentra levantado * * @return Entrega el indicador * @since empty * @throws Exception Error */ public boolean isStarted() throws Exception { return service; } /** * Método que entrega el estatus del Servidor * * @return Entrega el valor del Estatus. * @since empty * @throws Exception Error */ public String getStatus() throws Exception { return (this.service) ? "UP" : "DOWN"; } /** * Obtiene el valor de TodoClass * * @return El valor de TodoClass * @since empty */ @SuppressWarnings("unchecked") public Class getTodoClass() { return todoClass; } /** * Obtiene el valor de TaskDescription * * @return El valor de TaskDescription * @since empty */ public String getTaskDescription() { return taskDescription; } /** * Obtiene el valor de ExtraData * * @return El valor de ExtraData * @since empty */ public String getExtraData() { return "ULTIMA EJECUCION:" + this.lastExecution; } /** * Obtiene el valor de TaskParameters * * @return El valor de TaskParameters * @since empty */ public String getTaskParameters() { return taskParameters; } /** * Método que Permite desconectar el conector de la cola de entrada * * @since empty * @throws Exception Error */ public void disconnect() throws Exception { shutdown = true; service = false; this.addMessage("Tarea detenida ", DeviceEventTypes.FINISH); } /** * Método formal * * @return Entrega el valor de * @since empty * @throws Exception Error */ public Serializable receiveMessage() throws Exception { throw new UCIException("UCI-0001", "El controlador UCITask no permite la recepción de Mensajes"); } /** * Método que implementa el consumo de mensajes * * @since empty */ public void run() { while (service) { try { this.addMessage("Se inicia la Ejecucion de " + this.taskDescription, DeviceEventTypes.CONNECT); this.setLastInputMessage(""); if (!this.paralell) { ToDo td = (ToDo) this.todoClass.newInstance(); try { String result = td.execute(this.taskParameters); if (result != null) { this.lastExecution = result; this.addMessage("Finaliza la Ejecucion de " + this.taskDescription + " " + result, DeviceEventTypes.DISCONNECT); } } catch (Exception e) { UCILogger.getInstance().throwing(e); this.addMessage("La tarea " + this.taskDescription + ":" + e.getMessage(), DeviceEventTypes.ERROR); } } else { new Runner(this); } //Se ejecuta una vez al iniciar el Controlador. //Solo permite repetir ejecuciones para milisegundos //mayores a 0ms if (this.iTimer > 0) { sleep(this.iTimer * 1000); } else { shutdown(); break; } } catch (Exception e) { service = false; try { if (!this.shutdown) { UCILogger.getInstance().throwing(e); this.addMessage("" + e.getMessage(), DeviceEventTypes.ERROR); this.addMessage("Desconectado de la Cola de Entrada", DeviceEventTypes.FINISH); ErrorEvent.getInstance().process(this.name + " Desconectado: " + this.getServer() + " " + e.getMessage()); } } catch (Exception e1) { logger.throwing(e1); } break; } } } /** * Método formal * * @param pMessage Valor de * @param pProperties Valor de * @since empty * @throws Exception Error */ public void sendMessage(Serializable pMessage, Properties pProperties) throws Exception { throw new UCIException("UCI-0002", "El controlador UCITask no permite el envío de Mensajes"); } /** * Método que Permite detener el controlador de consumo de mensajes * * @since empty * @throws Exception Error */ public void shutdown() throws Exception { disconnect(); } /** * Método que Permite iniciar el consumo de mensajes * * @since empty * @throws Exception Error */ public void startup() throws Exception { service = true; } /** * Metodo que permite * * @param pParameters Valor de * @return Entrega * @exception Exception Error * @since empty */ @SuppressWarnings("unchecked") public String formatParameters(Map pParameters) throws Exception { String data = ""; data += (String) pParameters.get(TODO_CLASS); if (data == null) { throw new UCIException("PARAM-0014", "TODO_CLASS: CLASE A EJECUTAR REQUERIDA"); } Integer timer = null; try { timer = Integer.parseInt((String) pParameters.get(TIMER)); } catch (Exception e) { throw new UCIException("PARAM-0014", "TIMER: Se esperaba un Numero"); } if (timer == null) { throw new UCIException("PARAM-0014", "TIMER: TIEMPO DE ESPERA REQUERIDO"); } data += "#" + timer; String des = (String) pParameters.get(DESCRIPTION); if (des == null) { throw new UCIException("PARAM-0014", "DESCRIPCION: DESCRIPCION DE LA TAREA REQUERIDA"); } data += "#" + des; String param = (String) pParameters.get(PARAMETERS); if (param == null) { throw new UCIException("PARAM-0014", "PARAMETROS: PARAMETROS DE LA TAREA REQUERIDO"); } data += "#" + param; des = (String) pParameters.get(PARALELL); if (des != null) { if (des.compareTo("true") != 0) { des = "false"; } data += "#" + des; } return data; } /** * Metodo que permite * * @param pParameters Valor de * @return Entrega * @exception Exception Error * @since empty */ @SuppressWarnings("unchecked") public Map parseParametes(String pParameters) throws Exception { Map m = this.initParameters(); if (pParameters == null || pParameters.compareTo("") == 0) { return m; } StringTokenizer st = new StringTokenizer(pParameters, "#"); List l = new ArrayList(); while (st.hasMoreElements()) { l.add((String) st.nextElement()); } if (l.size() != 3 && l.size() != 4) { throw new UCIException("PARAM-0014", "ERROR DE CONFIGURACION"); } ParameterDetail d = (ParameterDetail) m.get(TODO_CLASS); try { d.setValue((String) l.get(0)); } catch (Exception e) { throw new UCIException("PARAM-0014", "CLASE A EJECUTAR: REQUERIDA"); } d = (ParameterDetail) m.get(TIMER); try { d.setValue("" + Integer.parseInt(l.get(1))); } catch (Exception e) { throw new UCIException("PARAM-0014", "TIMER: SE ESPERABA UN NUMERO"); } d = (ParameterDetail) m.get(DESCRIPTION); try { d.setValue((String) l.get(2)); } catch (Exception e) { throw new UCIException("PARAM-0014", "DESCRIPCION: REQUERIDA"); } d = (ParameterDetail) m.get(PARAMETERS); try { d.setValue((String) l.get(3)); } catch (Exception e) { throw new UCIException("PARAM-0014", "PARAMETROS: REQUERIDA"); } d = (ParameterDetail) m.get(PARALELL); try { if (l.size() > 4) { d.setValue(Boolean.valueOf((String) l.get(4)).toString()); } } catch (Exception e) { throw new UCIException("PARAM-0014", "PARALELO: CAMPO BOOLEANO"); } return m; } /** * Metodo que permite * * @return Entrega * @exception Exception Error * @since empty */ private Map initParameters() throws Exception { Map m = new HashMap(); ParameterDetail d = new ParameterDetail(TODO_CLASS, "Clase a ejecutar", Class.class, true); m.put(d.getName(), d); d = new ParameterDetail(TIMER, "Tiempo de espera entre ejecuciones", Integer.class, false); m.put(d.getName(), d); d = new ParameterDetail(DESCRIPTION, "Descripcion de la Tarea", String.class, false); m.put(d.getName(), d); d = new ParameterDetail(PARAMETERS, "Parametros de ejecucion de la tarea", String.class, false); m.put(d.getName(), d); d = new ParameterDetail(PARALELL, "Indicador de si las ejecuciones de la Tarea se pueden ejecutar en paralelo", Boolean.class, false); m.put(d.getName(), d); return m; } }