Create a custom trigger (Example 1)
- Updated: 2023/08/04
Create a custom trigger (Example 1)
Package SDK provides tools to build your custom trigger that automate actions based on predefined conditions.
In this section, you will learn how to create an interval trigger using Automation Anywhere's Package SDK. A sample class called
TriggerDemo
is used to explain its functionality step by step.
By the end, you will have a solid understanding of how to build your own custom
triggers using Package SDK:
Procedure
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;
}
}
Next steps
In the above code sample describes the various methods and annotations used to create and manage the trigger. By understanding the code and its functionality, you are now equipped to create your own interval triggers using Package SDK. Experiment with different intervals and trigger actions to automate your business processes effectively.
The above article is a just a sample, and you need to refine and customize it further based on your specific requirements and target audience.