Custom AQL function utilities
Use custom AQL function utilities.
Utils.concurrency.readLock
/**
* Acquire a read lock against the global lock.
*
* If the write lock is not held by another thread, this returns immediately.
* If the write lock is held by another thread then the current thread becomes
* disabled for thread scheduling purposes and lies dormant until
* the read lock has been acquired.
*/
void readLock()
JavaScript example:
Utils.concurrency.readLock();
try { /*Do something*/ }
finally { Utils.concurrency.readUnlock(); }
Utils.concurrency.readLock(String name)
/**
* Acquire a read lock against the given name.
* If a lock by the given name does not exist yet, it will be created.
*
* If the write lock is not held by another thread, this returns immediately.
* If the write lock is held by another thread then the current thread becomes
* disabled for threadscheduling purposes and lies dormant until
* the read lock has been acquired.
*
* @param name The name of the lock to acquire a read lock against.
* If null, global lock is used.
*/
void readLock(String name)
JavaScript example:
Utils.concurrency.readLock("my_lock");
try { /*Do something*/ }
finally { Utils.concurrency.readUnlock("my_lock"); }
Utils.concurrency.tryReadLock(long timeoutMsec)
/**
* Attempts to acquire a read lock against the global lock.
*
* If the write lock is not held by another thread, this returns immediately.
* If the write lock is held by another thread, this will wait
* a maximum of timeoutMsec millisecondsto acquire the read lock.
*
* @param timeoutMsec The maximum time to wait (in milliseconds) to acquire the lock
* <= 0 can be used to return immediately if the read lock can not be acquired.
* @return True if the read lock has been acquired, false otherwise.
*/
boolean tryReadLock(long timeoutMsec)
JavaScript example:
if(Utils.concurrency.tryReadLock(1000))
{
try { /* Lock acquired */ }
finally { Utils.concurrency.readUnlock(); }
}
else
throw "Failed to acquire lock in reasonable time";
Utils.concurrency.tryReadLock(String name, long timeoutMsec)
/**
* Attempts to acquire a read lock against the given name.
*
* If the write lock is not held by another thread, this returns immediately.
* If the write lock is held by another thread, this will
* wait a maximum of timeoutMsec millisecondsto acquire the read lock.
*
* @param name The name of the lock to acquire a read lock against.
* If null, global lock is used.
*
* @param timeoutMsec The maximum time to wait (in milliseconds)
* to acquire the lock.
* <= 0 can be used to return immediately if the read lock can not be acquired.
*
* @return True if the read lock has been acquired, false otherwise.
*/
boolean tryReadLock(String name, long timeoutMsec)
JavaScript example:
if(Utils.concurrency.tryReadLock("my_lock", 1000))
{
try { /* Lock acquired */ }
finally { Utils.concurrency.readUnlock("my_lock"); }
}
else
throw "Failed to acquire lock in reasonable time";
Utils.concurrency.readUnlock()
/**
* Releases the global read lock held by the current thread.
* You must currently be holding the global read lock,
* or an exception occurs.
* If the number of read locks held by all threads is now 0,
* then the lock is made available for write lock attempts.
*/
void readUnlock()
JavaScript example:
Utils.concurrency.readLock();
try { /*Do something*/ }
finally { Utils.concurrency.readUnlock(); }
Utils.concurrency.readUnlock(String name)
/**
* Releases the read lock against the given name held by the current thread.
* You must currently be holding the read lock by the given name,
* or an exception occurs.
* If the number of read locks held by all threads is now 0,
* then the lock is made available for write lock attempts.
*
* @param name The name of the lock to acquire a read lock against.
* If null, global lock is used.
*/
void readUnlock(String name)
JavaScript example:
Utils.concurrency.readLock("my_lock");
try { /*Do something*/ }
finally { Utils.concurrency.readUnlock("my_lock"); }
Utils.concurrency.writeLock()
/**
* Acquire a write lock against the global lock.
*
* If neither the read nor write lock are held by another thread,
* this returns immediately.
*
* If the write lock is held by another thread,
* then the current thread becomes disabled for thread
* scheduling purposes and lies dormant until
* the read lock has been acquired.
*/
void writeLock()
JavaScript example:
Utils.concurrency.writeLock();
try { /*Do something*/ }
finally { Utils.concurrency.writeUnlock(); }
Utils.concurrency.writeLock(String name)
/**
* Acquire a write lock against the given name.
*
* If neither the read nor write lock are held by another thread,
* this returns immediately.
* If the write lock is held by another thread then the current thread
* becomes disabled for threadscheduling purposes and lies dormant
* until the read lock has been acquired.
*
* @param name The name of the lock to acquire a write lock against.
* If null, global lock is used.
*/
void writeLock(String name)
JavaScript example:
Utils.concurrency.writeLock("my_lock");
try { /*Do something*/ }
finally { Utils.concurrency.writeUnlock("my_lock"); }
Utils.concurrency.tryWriteLock(long timeoutMsec)
/**
* Attempts to acquire a write lock against the global lock.
*
* If neither the read nor write lock are held by another thread,
* this returns immediately.
* If either the read or write lock is held by another thread,
* this will wait a maximum of timeoutMsec milliseconds
* to acquire the write lock.
*
* @param timeoutMsec The maximum time to wait (in milliseconds)
* to acquire the lock
* <= 0 can be used to return immediately,
* if the write lock can not be acquired.
* @return True if the write lock has been acquired, false otherwise.
*/
boolean tryWriteLock(long timeoutMsec)
JavaScript example:
if(Utils.concurrency.tryWriteLock(1000))
{
try { /* Lock acquired */ }
finally { Utils.concurrency.writeUnlock(); }
}
else
throw "Failed to acquire lock in reasonable time";
Utils.concurrency.tryWriteLock(String name, long timeoutMsec)
/**
* Attempts to acquire a write lock against the given name.
*
* If neither the read nor write lock are held by another thread
* this returns immediately.
* If either the read or write lock is held by another thread,
* this will wait a maximum of timeoutMsec milliseconds
* to acquire the write lock.
*
* @param timeoutMsec The maximum time to wait (in milliseconds)
* to acquire the lock.
* <= 0 can be used to return immediately if the write lock can not be acquired.
*
* @param name The name of the lock to acquire a write lock against.
* If null, global lock is used.
*
* @return True if the write lock has been acquired, false otherwise.
*/
boolean tryWriteLock(String name, long timeoutMsec)
JavaScript example:
if(Utils.concurrency.tryWriteLock("my_lock", 1000))
{
try { /* Lock acquired */ }
finally { Utils.concurrency.writeUnlock("my_lock"); }
}
else
throw "Failed to acquire lock in reasonable time";
Utils.concurrency.writeUnlock()
/**
* Releases the global write lock held by the current thread.
* You must currently be holding the global write lock, or an exception occurs.
* If the number of write locks held by all threads is now 0,
* then the lock is made available for write lock attempts.
*/
void writeUnlock()
JavaScript example:
Utils.concurrency.writeLock("my_lock");
try { /*Do something*/ }
finally { Utils.concurrency.writeUnlock("my_lock");
Utils.concurrency.createAtomicBoolean()
/**
* @return A new instance of java.util.concurrent.atomic.AtomicBoolean
*/
java.util.concurrent.atomic.AtomicBoolean createAtomicBoolean()
JavaScript example:
var atomicBoolean = Utils.concurrency.createAtomicBoolean();
if(atomicBoolean.getAndSet(true))
return "Value has not changed";
Utils.concurrency.createAtomicInteger()
/**
* @return A new instance of java.util.concurrent.atomic.AtomicInteger
*/
java.util.concurrent.atomic.AtomicInteger createAtomicInteger()
JavaScript example:
var atomicInt =
Utils.concurrency.createAtomicInteger();atomicInt.set(5);
Utils.concurrency.createAtomicLong()
/**
* @return A new instance of java.util.concurrent.atomic.AtomicLong
*/
java.util.concurrent.atomic.AtomicLong createAtomicLong()
JavaScript example:
var atomicLong =
Utils.concurrency.createAtomicLong();atomicLong.set(5)
Utils.concurrency.createAtomicDouble()
/**
* @return A new instance of java.util.concurrent.atomic.AtomicDouble
*/
java.util.concurrent.atomic.AtomicDouble createAtomicDouble()
JavaScript example:
var atomicDouble = Utils.concurrency.createAtomicDouble();
atomicDouble.set(5);
Utils.concurrency.createAtomicIntegerArray(int size)
/**
* @param Size of the array. Must be >= 0
* @return A new instance of java.util.concurrent.atomic.AtomicIntegerArray
* with the given size
*/
java.util.concurrent.atomic.AtomicIntegerArray createAtomicIntegerArray(int size)
JavaScript example:
var atomicIntArray = Utils.concurrency.createAtomicIntegerArray(5);
atomicIntArray.set(0, 25);
Utils.concurrency.createAtomicLongArray(int size)
/**
* @param Size of the array. Must be >= 0
* @return A new instance of java.util.concurrent.atomic.AtomicIntegerArray
* with the given size
*/
java.util.concurrent.atomic.AtomicIntegerArray createAtomicIntegerArray(int size)
JavaScript example:
var atomicLongArray = Utils.concurrency.createAtomicLongArray(5);
atomicLongArray.set(0, 25);
Utils.concurrency.createAtomicDoubleArray(int size)
/**
* @param Size of the array. Must be >= 0
* @return A new instance of java.util.concurrent.atomic.AtomicDoubleArray
* with the given size
*/
java.util.concurrent.atomic.AtomicDoubleArray createAtomicDoubleArray(int size)
JavaScript example:
var atomicDoubleArray = Utils.concurrency.createAtomicDoubleArray(5);
atomicDoubleArray.set(0, 25);
Utils.concurrency.createConcurrentMap()
/**
* @return Returns a new instance of
* java.util.concurrent.ConcurrentHashMap.ConcurrentHashMap,
* which is a thread safe map that accepts any key or value
*/
java.util.concurrent.ConcurrentHashMap.ConcurrentHashMap createConcurrentMap()
JavaScript example:
var myMap = Utils.concurrency.createConcurrentMap();
myMap.put("some_key", "some_value");
myMap.put("some_other_key", 25);
Utils.concurrency.createConcurrentSet()
/**
* @return Returns a new thread safe set that accepts any value,
* backed by java.util.concurrent.ConcurrentHashMap.ConcurrentHashMap
*/
java.util.concurrent.ConcurrentHashMap.ConcurrentHashMap createConcurrentSet()
JavaScript example:
var mySet = Utils.concurrency.createConcurrentSet();
mySet.add("something");
mySet.add(25);
Utils.crypto.aesEncrypt(String data)
/**
* Given a String, the frameworks AES encryption protocol will be invoked
* to return an encrypted String.
*
* @param data The String that will be encrypted.
* @return The encrypted String. Null if null data was provided.
*/
String aesEncrypt(String data)
JavaScript example:
var myEncryptedData = Utils.crypto.aesEncrypt
("my plaintext data,
preferably not stored here as a string");
Utils.crypto.aesDecrypt(String data)
/**
* Given an String that is encrypted by the frameworks AES encryption protocol,
* return the decrypted value.
*
* @param data The String that was encrypted by the framework's
* AES encryption protocol.
* @return The decrypted String. Null if null data was provided.
*/
String aesDecrypt(String data)
JavaScript example:
var myData = Utils.crypto.aesDecrypt("my encrypted data");
Utils.general.base64Decode(String value)
/**
* Given a String encoded as base64, return the original value
* @param value The base64 value to decode
* @return The decoded value. Null if value was null
*/
String base64Decode(String value)
JavaScript example:
var myAuth = Utils.general.base64Decode("my base64 encoded auth
Utils.config.readNamespaceFile(String relPath)
/**
* Given the path to a file relative to the namespace configuration
* directory for the function assigned to this utility,
* read it and return a String representation,
* decoded using default character set of this JVM (typically UTF-8).
* The file must exist, or an exception is thrown.
* The file must be readable, or an exception is thrown.
* If the relative path leads to a file that is not a child
* of the proper configuration directory, an exception is thrown.
*
* The full path structure is:
* /${CUSTOM_FUNCTION_CONFIG_DIR}/namespaces/${namespace}/${relPath}
*
* @param relPath The path to the file, relative to the namespace configuration
* directory for the function assigned to this utility
* @return A String representing the file's content in the default character set.
*/
String readNamespaceFile(String relPath)
JavaScript example:
var myFileContent = Utils.config.readNamespaceFile("test.txt");
Utils.config.readNamespaceFile(String relPath, boolean forceExist)
/**
* Given the path to a file relative to the namespace configuration
* directory for the function assigned to this utility,
* read it and return a String representation,
* decoded using default character setof this JVM (typically UTF-8).
* The file must be readable, or an exception is thrown.
* If the relative path leads to a file that is not a child
* of the proper configuration directory, an exception is thrown.
*
* The full path structure is:
* /${CUSTOM_FUNCTION_CONFIG_DIR}/namespaces/${namespace}/${relPath}
*
* @param relPath The path to the file, relative to the namespace configuration
* directory for the function assigned to this utility
*
* @param forceExist If true, and the file does not exist, an exception if thrown.
* If false, and the file does not exist, an empty Map is returned.
* @return A String representing the file's content in the default character set.
* An empty String if forceExist was false and the file does not exist.
*/
String readNamespaceFile(String relPath, boolean forceExist)
JavaScript example:
var myFileContent = Utils.config.readNamespaceFile("test.txt", false);
Utils.config.readNamespaceFile(String relPath, boolean forceExist, String charset)
/**
* Given the path to a file relative to the namespace configuration
* directory for the function assigned to this utility,
* read it and return a String representation,
* decoded using the given character set.
* The file must be readable, or an exception is thrown.
* If the relative path leads to a file that is not a child
* of the proper configuration directory, an exception is thrown.
*
* The full path structure is:
* /${CUSTOM_FUNCTION_CONFIG_DIR}/namespaces/${namespace}/${relPath}
*
* @param relPath The path to the file, relative to the
* namespace configuration directory for the function assigned to this utility
*
* @param forceExist If true, and the file does not exist, an exception if thrown.
* If false, and the filedoes not exist, an empty Map is returned.
*
* @param charset The character set (encoding) to use when reading the file.
* If null, the JVM default is used, usually UTF-8.
*
* @return A String representing the files content in the given character set.
* An empty String if forceExist was false and the file does not exist.
*/
String readNamespaceFile(String relPath, boolean forceExist, String charset)
JavaScript example:
var myFileContent = Utils.config.readNamespaceFile("test.txt", false, "UTF-8");
Utils.config.readNamespacePropertiesFile(String relPath)
/**
* Given the path to a file relative to the namespace configuration
* directory for the function assigned to this utility,
* read it and return a Map of properties.
* The format is assumed to be the Java compatible key/value pair format.
* The file must exist, or an exception is thrown.
* The file must be readable, or an exception is thrown.
* If the relative path leads to a file that is not a child
* of the proper configuration directory, an exception is thrown.
*
* The full path structure is:
* /${CUSTOM_FUNCTION_CONFIG_DIR}/namespaces/${namespace}/${relPath}
*
* @param relPath The path to the file, relative to the namespace configuration
* directory for the function assigned to this utility.
*
* @param forceExist If true, and the file does not exist, an exception if thrown.
* If false, and the file does not exist, an empty Map is returned.
*
* @return A map of properties read from the file
*/
Map<String, String> readNamespacePropertiesFile(String relPath)
JavaScript example:
var myProperties = Utils.config.readNamespacePropertiesFile("test.properties");
var myValue = myProperties.get("my_key");
Utils.config.readNamespacePropertiesFile(String relPath, boolean forceExist)
/**
* Given the path to a file relative to the namespace configuration
* directory for the function assigned to this utility,
* read it and return a Map of properties.
* The format is assumed to be the Java compatible key/value pair format.
* The file must be readable, or an exception is thrown.
* If the relative path leads to a file that is not a chil
* d of the proper configuration directory, an exception is thrown.
*
* The full path structure is:
* /${CUSTOM_FUNCTION_CONFIG_DIR}/namespaces/${namespace}/${relPath}
*
* Charset used will be the default charset in this JVM
*
* @param relPath The path to the file, relative to the namespace configuration
* directory for the function assigned to this utility.
*
* @param forceExist If true, and the file does not exist, an exception if thrown.
* If false, and the file does not exist, an empty Map is returned.
*
* @return A map of properties read from the file.
* An empty map if forceExist was false and the file does not exist.
*/
Map<String, String> readNamespacePropertiesFile(String relPath, boolean forceExist)
JavaScript example:
var myProperties =
Utils.config.readNamespacePropertiesFile("test.properties", false);
var myValue = myProperties.get("my_key");
Utils.config.readNamespacePropertiesFile(String relPath, boolean forceExist, String charset)
/**
* Given the path to a file relative to the namespace configuration
* directory for the function assigned to this utility,
* read it using the given character set and return a Map of properties.
* The format is assumed to be the Java compatible key/value pair format.
* The file must be readable, or an exception is thrown.
* If the relative path leads to a file that is not a child
* of the proper configuration directory, an exception is thrown.
*
* The full path structure is:
* /${CUSTOM_FUNCTION_CONFIG_DIR}/namespaces/${namespace}/${relPath}
*
* @param relPath The path to the file, relative to the namespace configuration
* directory for the function assigned to this utility.
*
* @param forceExist If true, and the file does not exist, an exception if thrown.
* If false, and the file does not exist, an empty Map is returned.
*
* @param charset The character set (encoding) to use when reading the file.
* If null, the JVM default is used, usually UTF-8.
*
* @return A map of properties read from the file.
* An empty map if forceExist was false and the file does not exist.
*/
Map<String, String>
readNamespacePropertiesFile(String relPath, boolean forceExist, String charset)
JavaScript example:
var myProperties =
Utils.config.readNamespacePropertiesFile
("test.properties", false, "UTF-8");
var myValue = myProperties.get("my_key");
Utils.http.urlEncode(String value)
/**
* URL encodes the given value
* @param value The value to encode. Null returns null
* @return The URL encoded value
*/
String urlEncode(String value)
JavaScript example:
var myEncodedPathParam = Utils.http.urlEncode("my Path parameter");
Utils.http.invokeHTTP(String method, String uriStr, Integer expectedResponseCode, Map<String, String> headers, Map<String, Object> parameters, String body)
/**
* This method is purposely monolithic. It will be deprecated when we provide
* a proper (and reliable) HttpClient implementation directly
*
* Perform an HTTP request with the given parameters
* and return the response body as a String.
*
* IMPORTANT: All request content (parameters, and body)
* is assumed to be UTF-8.
*
* @param method The HTTP method to use:
* [GET, PUT, POST, DELETE, OPTIONS, TRACE, HEAD, PATCH].
* If null or empty, GET is used.
* If not recognized, RuntimeException is thrown.
*
* @param uri The address, which is not already escaped.
* Query parameters should only be provided as part of this address
* if the parameters parameter is not specified.
*
* @param expectedResponseCode The response code you expect,
* or null if you don't care.
* Throws RuntimeException if response code does not match.
*
* @param headers A map of headers. Note that they are case
* and whitespace insensitive.
*
* @param parameters A map of parameters.
* If the request method does not supporta request body,
* they will be included in the URI.
* If the request method does support a request body,
* they will be translated to URLFormEncoded,
* and use the application/x-www-form-urlencoded
* content type; the payload will also be ignored.
*
* @param body The raw request body as a String.
* Will only be used if the request supports a request body.
* A Content-Type header should always be provided,
* but Content-Length is automatically calculated.
* IMPORTANT: This is not compatible with extremely large data sets.
* No streaming implementation is provided either.
*
* @return Content The response body as a string.
* The character encoding used to construct it will be that which was
* specified by the response Content-Type header.
* If none is available, it will default to UTF-8
*/
String invokeHTTP(String method, String uriStr, Integer expectedResponseCode,
Map<String, String> headers, Map<String, Object>
parameters, String body)
JavaScript example:
var responseBody = Utils.http.invokeHTTP
("GET", "https://myServer/api/my_endpoint",
200, {"Token":"MyToken"}, {}, null);
Utils.concurrency.createConcurrentList()
/**
* @return Returns a new thread safe list implemented by
* java.util.concurrent.CopyOnWriteArrayList
*/
java.util.concurrent.CopyOnWriteArrayList createConcurrentList()
JavaScript example:
var myList
= Utils.concurrency.createConcurrentList(); myList.add("something");
myList.add(25);
Utils.log.info()
/**
* Log the given message through QRadar using a log level of INFO.
* @param msg The message to log.
* Will be prefixed with relevant state and script information.
*/
void info(String msg)
JavaScript example:
Utils.log.info("My message");
Utils.log.warn()
/**
* Log the given message through QRadar using a log level of WARN.
* @param msg The message to log.
* Will be prefixed with relevant state and script information.
*/
void warn(String msg)
JavaScript example:
Utils.log.warn("My message");
Utils.log.error()
/**
* Log the given message through QRadar using a log level of ERROR.
* @param msg The message to log.
* Will be prefixed with relevant state and script information.
*/
void error(String msg)
JavaScript example:
Utils.log.error("My message");
Utils.log.debug()
/**
* Log the given message through QRadar using a log level of DEBUG.
* Typically this log will be ignored unless enabled
* through QRadar logging configuration.
* @param msg The message to log.
* Will be prefixed with relevant state and script information.
*/
void debug(String msg)
JavaScript example:
Utils.log.debug("My message");
When you use JavaScript, you also have access to standard ECMA utilities such as "JSON". For more information, see the Mozilla Developer Network (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse).