Créer un déclencheur personnalisé (exemple 1)

Le package SDK fournit des outils pour créer des déclencheurs personnalisés qui automatisent des actions basées sur des conditions prédéfinies.

Dans cette section, vous apprendrez à créer un déclencheur d\'intervalle à l\'aide du package SDK d\'Automation Anywhere. Un exemple de classe appelé TriggerDemo est utilisé afin d\'expliquer sa fonctionnalité étape par étape. À l\'issue de cette section, vous aurez une bonne compréhension de la façon de créer vos propres déclencheurs personnalisés à l\'aide du package SDK :

Procédure

  1. Dépendances et package : l\'exemple de code utilise plusieurs importations et est organisé dans le package com.automationanywhere.botcommand.samples.trigger.
  2. Annotations : le code utilise plusieurs annotations fournies par le package SDK afin de définir et de configurer le déclencheur. Ces annotations comprennent :
    1. @BotCommand: spécifie que cette classe représente un déclencheur. Vous spécifiez cette annotation à l\'aide de la ligne @BotCommand(commandType = BotCommand.CommandType.Trigger) . Lorsque vous spécifiez cette annotation, il s\'agit d\'un type de commande Trigger. Elle est alors visible dans la section Déclencheur de l\'éditeur de robots.
    2. @CommandPkg : fournit des métadonnées sur le déclencheur, telles que l\'étiquette, la description, l\'icône et le type de retour. Le type de retour est toujours défini sur RECORD, comme le montre l\'exemple suivant.
    3. @TriggerId: indique l\'identifiant unique attribué à chaque instance de déclenchement.
    4. @DéclencheurConsommateur: Spécifie la fonction consommateur à invoquer lorsque la condition de déclenchement est remplie.
    5. @CommencerÉcouter: identifie la méthode responsable du démarrage du déclencheur.
      Conseil : @StartListen est utilisé pour exécuter un déclencheur et est analogue à @Execute dans le cas d\'un robot.
    6. @ArrêterTousLesDéclencheurs: Identifie la méthode utilisée pour annuler tous les déclencheurs.
    7. @StopListen: identifie la méthode responsable de l\'annulation d\'un déclencheur spécifique.
  3. Exécution du déclencheur : la logique d\'exécution du déclencheur est mise en œuvre dans la méthode startTrigger à l\'aide de l\'annotation @StartListen. Dans cet exemple, une classe TimerTask est programmée de façon à s\'exécuter à des intervalles réguliers définis par l\'utilisateur. Lorsque l\'heure prévue est atteinte, la méthode run de la classe TimerTask est exécutée, ce qui déclenche la méthode consumer.accept. Le consommateur accepte la valeur RecordValue renvoyée par la méthode getRecordValue.
    Conseil : La valeur RecordValue peut aussi être utilisée dans la logique de votre robot.
  4. Méthode getRecordValue : la méthode getRecordValue crée un objet RecordValue et le renseigne avec une liste de schémas et de valeurs. Dans cet exemple, le schéma triggerType est ajouté avec la valeur Déclencheur d\'intervalle correspondante.
  5. Méthodes StopListen et StopAllTriggers : ces méthodes sont annotées par @StopListen et @StopAllTriggers, respectivement. Elles sont chargées d\'annuler la ou les tâches de déclenchement et de les supprimer de la carte des tâches.
  6. Méthodes d\'aide supplémentaires : le code comprend également des méthodes getter et setter pour les variables triggerUid et 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;
	}
}

Étapes suivantes

L\'exemple de code ci-dessus décrit les différentes méthodes et annotations utilisées pour créer et gérer le déclencheur. Maintenant que vous comprenez le code et ses fonctionnalités, vous pouvez créer vos propres déclencheurs d\'intervalle à l\'aide du package SDK. Testez différents intervalles et actions de déclenchement pour automatiser efficacement vos processus métier.

L\'article ci-dessus n\'est qu\'un exemple, et vous devez l\'affiner et le personnaliser en fonction de vos besoins spécifiques et de votre public cible.