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");
Note:

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).