Crear un activador personalizado (ejemplo 1)

Package SDK proporciona herramientas para crear su activador personalizado que automatiza acciones basadas en condiciones predefinidas.

En esta sección, aprenderá a crear un activador de intervalo utilizando Package SDK de Automation Anywhere. Se utiliza una clase de ejemplo llamado TriggerDemo para explicar su funcionalidad paso a paso. Al final, usted tendrá una comprensión sólida de cómo construir sus propios activadores personalizados utilizando Package SDK:

Procedimiento

  1. Dependencias y Package: El ejemplo de código utiliza varias importaciones y está organizado dentro del paquete com.automationanywhere.botcommand.samples.trigger.
  2. Anotaciones: El código utiliza varias anotaciones proporcionadas por Package SDK para definir y configurar el activador. Estas anotaciones incluyen:
    1. @BotCommand: Especifica que esta clase representa un activador. Esto se especifica mediante la línea @BotCommand(commandType = BotCommand.CommandType.Trigger) . Cuando especifique que es un tipo de comando Trigger, se verá en la sección Activar dentro del editor de Bot.
    2. @CommandPkg: Proporciona metadatos sobre el activador, como la etiqueta, la descripción, el icono y el tipo de retorno. El tipo de retorno siempre se establece en RECORD como se muestra en el siguiente ejemplo.
    3. @TriggerId: Indica el identificador único asignado a cada instancia de activación.
    4. @TriggerConsumer: Especifica la función consumidora que se invocará cuando se cumpla la condición de activación.
    5. @StartListen: Marca el método responsable de iniciar el activador.
      Consejo: @StartListen se utiliza para ejecutar un activador y es análogo a @Execute en el caso de un bot.
    6. @StopAllTriggers: Identifica el método utilizado para cancelar todos los activadores.
    7. @StopListen: Identifica el método responsable de cancelar un activador específico.
  3. Ejecución de Activadores: La lógica de ejecución del activador se implementa en el método startTrigger utilizando la anotación @StartListen. En este ejemplo, se programa una TimerTask para que se ejecute a intervalos regulares definidos por el usuario. Cuando se alcanza la hora programada, se ejecuta el método run del TimerTask, activando el consumer.accept. El consumidor acepta el RecordValue devuelto por el método getRecordValue.
    Consejo: RecordValue también está disponible para usar dentro de la lógica de su bot.
  4. MétodogetRecordValue: El método getRecordValue crea un objeto RecordValue y lo rellena con una lista de esquemas y valores. En este ejemplo, se añade el esquema triggerType con el valor correspondiente Interval Trigger.
  5. Métodos StopListen y StopAllTriggers : Estos métodos están anotados con @StopListen y @StopAllTriggers, respectivamente. Se encargan de cancelar la(s) tarea(s) desencadenante(s) y de eliminarlas del mapa de tareas.
  6. Métodos auxiliares adicionales: El código también incluye métodos getter y setter para las variables triggerUid y consumer.
package com.automationanywhere.botcommand.samples.trigger;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;

import javax.sql.DataSource;

import com.automationanywhere.botcommand.data.Value;
import com.automationanywhere.botcommand.data.impl.RecordValue;
import com.automationanywhere.botcommand.data.impl.StringValue;
import com.automationanywhere.botcommand.data.model.Schema;
import com.automationanywhere.botcommand.data.model.record.Record;
import com.automationanywhere.botcommand.samples.exceptions.DemoException;
import com.automationanywhere.commandsdk.annotations.*;
import org.apache.commons.dbcp2.BasicDataSource;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.automationanywhere.botcommand.exception.BotCommandException;
import com.automationanywhere.commandsdk.annotations.rules.GreaterThan;
import com.automationanywhere.commandsdk.annotations.rules.NotEmpty;
import com.automationanywhere.commandsdk.annotations.rules.NumberInteger;
import com.automationanywhere.commandsdk.model.AttributeType;
import com.automationanywhere.commandsdk.model.DataType;
import com.automationanywhere.core.security.SecureString;

import static com.automationanywhere.commandsdk.model.DataType.RECORD;

/**
 * This example is an extension of the timer based trigger {@link TriggerDemo} and demonstrates the
 * pull mechanism.
 * Trigger will check the DB at regular interval and if the records returned by
 * user provided SQL is more than 0 then it will get triggered.
 * NOTE 1: This class is for illustrative purpose only not safe for use in production.
 * NOTE 2: Please add the valid DB driver in build gradle to run this example.
 * 
 */
@BotCommand(commandType = BotCommand.CommandType.Trigger)
@CommandPkg(label = "JDBC Query Trigger", description = "JDBC Query Trigger", icon = "jdbc.svg", name = "jdbcQueryTrigger",
		return_type = RECORD, return_name = "TriggerData", return_description = "Available keys: triggerType")
public class DBStatus {
	
	private static Logger logger = LogManager.getLogger(DBStatus.class);
	
	
	// Map storing multiple tasks
	private static final Map<String, TimerTask> taskMap = new ConcurrentHashMap<>();
	private static final Timer TIMER = new Timer(true);

	@TriggerId
	private String triggerUid;
	@TriggerConsumer
	private Consumer consumer;

	/*
	 * Starts the trigger.
	 */
	@StartListen
	public void startTrigger(
			@Idx(index="1", type = AttributeType.TEXT)
			@Pkg(label = "Please provide the database driver class")
			@NotEmpty
			String driverClassName,
			
			@Idx(index="2", type = AttributeType.TEXT)
			@Pkg(label = "Please provide the Jdbc connection string")
			@NotEmpty
			String jdbcUrl,
			
			@Idx(index="3", type = AttributeType.TEXT)
			@Pkg(label = "Please provide the user Name")
			@NotEmpty
			String userName,
			
			@Idx(index="4", type = AttributeType.CREDENTIAL)
			@Pkg(label = "Please provide the password")
			@NotEmpty
			SecureString password,
			
			@Idx(index="5", type = AttributeType.TEXT)
			@Pkg(label = "Please provide the SQL to check the records")
			@NotEmpty
			String sqlQuery,
			
			@Idx(index = "6", type = AttributeType.NUMBER)
			@Pkg(label = "Please provide the interval to query in seconds", default_value = "300", default_value_type = DataType.NUMBER)
			@GreaterThan("0")
			@NumberInteger
			@NotEmpty
			Double interval) {
		
		DataSource dataSource = getDataSource(driverClassName, jdbcUrl, userName, password);
		
		TimerTask timerTask = new TimerTask() {

			@Override
			public void run() {
				logger.debug("checking DB");
				try {
					if(checkRecordsExist(dataSource.getConnection(), sqlQuery)){
						consumer.accept(getRecordValue());
						return;
					}
				} catch (SQLException e) {
					logger.warn(e.getMessage(),e);
					logger.warn("Trigger is still running.");
				}
				logger.debug("no records found");

			}
		};

		taskMap.put(this.triggerUid, timerTask);
		TIMER.schedule(timerTask, interval.longValue(), interval.longValue());
	}

	private RecordValue getRecordValue() {
		List<Schema> schemas = new LinkedList<>();
		List<Value> values = new LinkedList<>();
		schemas.add(new Schema("triggerType"));
		values.add(new StringValue("DBStatus"));

		RecordValue recordValue = new RecordValue();
		recordValue.set(new Record(schemas,values));
		return recordValue;
	}
	/*
	 * Cancel all the task and clear the map.
	 */
	@StopAllTriggers
	public void stopAllTriggers() {
		taskMap.forEach((k, v) -> {
			if (v.cancel()) {
				taskMap.remove(k);
			}
		});
	}

	/*
	 * Cancel the task and remove from map
	 *
	 * @param triggerUid
	 */
	@StopListen
	public void stopListen(String triggerUid) {
		if (taskMap.get(triggerUid).cancel()) {
			taskMap.remove(triggerUid);
		}
	}

    public static DataSource getDataSource(String driverClassName, String url, String userName,SecureString password) {
    	BasicDataSource ds = new BasicDataSource();
    	ds.setDriverClassName(driverClassName);
    	ds.setUrl(url);
    	ds.setUsername(userName);
    	ds.setPassword(password.getInsecureString());
        return ds;
    }
	
    public static boolean checkRecordsExist(Connection con, String query)
    	    throws SQLException {
			
    	    Statement stmt = null;
    	    try {
    	        stmt = con.createStatement();
    	        ResultSet rs = stmt.executeQuery(query);
    	        rs.last();
    	        if(rs.getRow() > 0)
    	        	return true;
    	    } catch (SQLException e ) {
    	        throw new DemoException("Problem running statemnt", e);
    	    } finally {
    	        if (stmt != null) { stmt.close(); }
    	    }
    	    
    	    return false;
    	}
    
	public String getTriggerUid() {
		return triggerUid;
	}

	public void setTriggerUid(String triggerUid) {
		this.triggerUid = triggerUid;
	}

	public Consumer getConsumer() {
		return consumer;
	}

	public void setConsumer(Consumer consumer) {
		this.consumer = consumer;
	}
}

Qué hacer a continuación

En el ejemplo de código anterior se describen los distintos métodos y anotaciones utilizados para crear y gestionar el activador. Al comprender el código y su funcionalidad, ahora está equipado para crear sus propios activadores de intervalo utilizando Package SDK. Experimente con diferentes intervalos y acciones desencadenantes para automatizar eficazmente sus procesos empresariales.

El artículo anterior es sólo un ejemplo, por lo que deberá perfeccionarlo y personalizarlo en función de sus necesidades específicas y de su público objetivo.