.. index:: built-in functions, backend ****************************** Backend built-in functions ****************************** This API page describes built-in functions defined on Backend level. As the Backend component integrates an Interpreter, all :ref:`Interpreter built-in functions` are still available. When the Backend component starts, it builds-up the Backend Scolvo script using the backend.scolvo as entry point. The built-up script is loaded to the Interpreter and holds the Backend business logic. Backend built-in function groups ================================= * Scheduling functions * Authentication related functions * Internal communication functions * External communication functions * Document handling functions * Reporting functions * Misc functions .. index:: Backend scheduling functions Scheduling functions ===================== This function group implements functionality for scripting-space automation, it supports **addJob**, **addImmediateJob** and **deleteJob** functions. .. index:: addJob() Backend built-in function addJob() function ------------------ This function defines a repeated job for the Backend. *Function syntax* .. void addJob(cronExpression, jobName, groupName, triggerExpression) Where the given *cronExpression* is a mandatory String describing the repetition, the *jobName* mandatory String defines the name of the repeated job, the *groupName* mandatory String defines the job group and the *triggerExpression* defines the repeating expression (usually event name without 'on', e.g.: 'CalculateUserFees'). The `CRON expression `_ is validated by Quartz scheduler during appropriate object creation, next invoke time is logged as debug information for validation purposes. Job is created with the unique name of groupName - jobName pair, which can be used when deleting the job. .. code-block:: scolvoscript :caption: Example addJob() function call :linenos: function initScheduledJobs() { addJob("0 0 8 ? * * *", "morningDataImportJob", "DataImport", "MorningDataImport"); addJob("0 0 12 ? * * *", "noonDataImportJob", "DataImport", "NoonDataImport"); } initScheduledJobs(); function onMorningDataImport(originId) { importUsers(); importData(); } function onNoonDataImport(originId) { importData(); } .. .. index:: addImmediateJob() Backend built-in function addImmediateJob() function --------------------------- This function defines a start-time executed job for the Backend Scheduler. *Function syntax* .. void addImmediateJob(jobName, groupName, triggerExpression) Where the given *jobName* mandatory String defines the name of the repeated job, the *groupName* mandatory String defines the job group and the *triggerExpression* defines the repeating expression (usually event name without 'on', e.g.: 'CalculateStartTimeFees'). .. code-block:: scolvoscript :caption: Example addImmediateJob() function call :linenos: function initScheduledJobs() { addImmediateJob("startTimeFeeCalculationJob", "Statistics", "CalculateFeesAtStart"); } initScheduledJobs(); function onCalculateFeesAtStart(originId) { calculateFees(); } .. .. index:: deleteJob() Backend built-in function deleteJob() function --------------------------- This function deletes a job defined with jobGroup and jobName. It returns if the action is successful. *Function syntax* .. boolean deleteJob(jobName, groupName) Where the given *jobName* mandatory String and the *groupName* mandatory String defines the job. .. code-block:: scolvoscript :caption: Example deleteJob() function call :linenos: function cleanUpUnnecessaryJobs() { if (deleteJob("morningDataImportJob", "DataImport")) { info("Job has been deleted successfully."); } else { info("Scheduled job DataImport - morningDataImportJob delete has been failed"); } } .. .. index:: Backend authentication functions Authentication functions ========================= This function group implements functionality for managing users security-related representation in the Authentication Service (actually a Keycloak Server). Defined functions are: * createKeycloakUser * updateKeycloakUser * deleteKeycloakUser * getAuthToken These function keep in-sync the Backend's User database and the Keycloak data. .. index:: createKeycloakUser() Backend built-in function createKeycloakUser() function ----------------------------- This function creates a user with given attributes, it returns the Keycloak id of the created user. *Function syntax* .. String createKeycloakUser(userConfig) Where the given *userConfig* contains the user attributes (see the example for details). Usual usage is when a new User created on administration UI or by self registration. .. code-block:: scolvoscript :caption: createKeycloakUser() function call in self registration events :linenos: function onSelfRegistering(originId) { var userDao = $IN.data.map; var userConfig = { "id": userDao.id, "enabled": true, "name": userDao.name, "email": userDao.email, "username": userDao.username, "password": userDao.password, "realmRoles": ["authenticated", "otherRelevantRole"] }; var keycloakUserId = createKeycloakUser(userConfig); debug("Created keycloak user is: " + keycloakUserId); userDao.put("keycloakId", keycloakUserId); userDao.put("role", "otherRelevantRole"); return userDao; } function onSelfRegistered(originId) { } .. .. code-block:: scolvoscript :caption: createKeycloakUser() function call in TypeDefinitionLifeCycle.scolvo where the User creation events are defined :linenos: function onUserInserting(originId) { var userDao = $IN.data.map; var userConfig = { "id": userDao.id, "enabled": true, "name": userDao.name, "email": userDao.email, "password": userDao.password, "username": userDao.username, "realmRoles": ["authenticated", userDao.role] }; return createKeycloakUser(userConfig); } function onUserInserted(originId) { var userDaoFromRequest = $IN.data.map; info("Updating created user with KeycloakId: " + $IN.data.preScriptResult + " ..."); var userDao = { "id": userDaoFromRequest.id, "keycloakId": $IN.data.preScriptResult, "changeType": "UPDATE" }; updateTypeDefinition("user", userDaoFromRequest.id, userDao); info("User has been updated with KeycloakId."); } .. .. index:: updateKeycloakUser() Backend built-in function updateKeycloakUser() function ----------------------------- This function updates a user definition with given attributes. *Function syntax* .. void updateKeycloakUser(userConfig) Where the given *userConfig* contains the user attributes (see the example for details). Usual usage is when a User update is done on administration UI or in the profile. .. code-block:: scolvoscript :caption: updateKeycloakUser() function call in TypeDefinitionLifeCycle.scolvo where the User modification events are defined :linenos: function onUserUpdating(originId) { } function onUserUpdated(originId) { var userDao = $IN.data.map; var userConfig = { "id": userDao.id }; if (userDao.containsKey("name")) { userConfig.put("name", userDao.name); } if (userDao.containsKey("email")) { userConfig.put("email", userDao.email); } if (userDao.containsKey("username")) { userConfig.put("username", userDao.username); } if (userDao.containsKey("role")) { userConfig.put("realmRoles", ["authenticated", userDao.role]); } if (userDao.containsKey("password")) { userConfig.put("password", userDao.password); } if (userDao.containsKey("status")) { userConfig.put("enabled", userDao.get("status") == "active"); } updateKeycloakUser(userConfig); } .. .. index:: deleteKeycloakUser() Backend built-in function deleteKeycloakUser() function ----------------------------- This function deletes a user definition identified by email address. *Function syntax* .. boolean deleteKeycloakUser(emailAddress) Where the given *emailAddress* is a String identifying a user. The result value reflects if the deletion is successful or not. Usual usage is when a User is deleted on the administration UI. .. code-block:: scolvoscript :caption: deleteKeycloakUser() function call in TypeDefinitionLifeCycle.scolvo where the User deletion events are defined :linenos: function onUserDeleting(originId) { var userInfo = $IN.data.map; var userDao = getUserById(userInfo.id); debug("Deleting user: " + userDao.email); if (deleteKeycloakUser(userDao.email)) { info("The user with email '" + userDao.email + "' has been successfully deleted."); } else { error("User delete in Keycloak has been failed."); } } function onUserDeleted(originId) { } .. .. index:: getAuthToken() Backend built-in function getAuthToken() function ----------------------------- This function gets a valid auth token for given email. Backend events usually contain the client authentication token (accessible form script space). For the cases where the authentication token is not yet defined, or it is not available, but the user's email and password are available, this function call gets a valid authentication token for further internal requests. For example at self-registration time there is no authentication token (as before the successful Keycloak registration it is not possible to get one), but we know the username and password - a valid token can be received and used for other internal service calls. *Function syntax* .. String getAuthToken(emailAddress, password) Where the given *emailAddress* and the *password* are Strings and the result access token is given in form of String. .. code-block:: scolvoscript :caption: getAuthToken() function call in self-registration :linenos: function onSelfRegistering(originId) { var userDao = $IN.data.map; var userConfig = { "id": userDao.id, "enabled": true, "name": userDao.name, "email": userDao.email, "username": userDao.username, "password": userDao.password, "realmRoles": ["authenticated", "someRoleName"] }; var keycloakId = createKeycloakUser(userConfig); debug("Created keycloak user is: " + keycloakId); var userToken = getAuthToken(userDao.email, userDao.password); // Do your logic, use the userToken as needed for internal calls // e.g. store it to be able to use in further requests putTheTokenToTheStore(userDao.id, userToken); userDao.put("keycloakId", keycloakId); userDao.put("role", roleEditor); return userDao; } function onSelfRegistered(originId) { var userDaoFromRequest = $IN.data.map; var token = getTheTokenFromTheStore(userDaoFromRequest.id); if (token != null) { var response = doTheSpecialInternalRequest(token); if (response.getStatusCode() == 200) { var someResult = response.getData(); sendWelcomeEmail(userDaoFromRequest.id, someResult); } else { error("Error when requesting some result: " + response.getData()); } } else { error("No token found for the given user."); } } .. .. index:: Internal communication functions Internal Communication functions ================================== This function group implements functionality for internal communication between clients. It supports *broadcastDatagram* function sending internal message to all or to a dedicated client and function *createDataSyncElement* helping in the creation of data synchronization message elements. .. index:: broadcastDatagram() Backend built-in function broadcastDatagram() function ----------------------------- It has the *dataChangeDg* - a Map (mandatory parameter) - and the *clientId* parameter - an optional String parameter. *Function syntax* .. void broadcastDatagram(dataChangeDg, clientId) Where the valid keys of the dataChangeDg Map parameter are: * originId - String (mandatory key), represents the origin Id, * typeDefinition - String (mandatory key), defined the name of the type definition, * typeDefinitionVersion - long (mandatory key), represents the version number of the type definition, * changeSet - List> parameter (mandatory key, the list must be non-empty), it holds the row definitions. And the clientId can be the clientId of an existing client or null to send the message to all clients). .. code-block:: scolvoscript :caption: Example broadcastDatagram() function call in client-backend-client communication case :linenos: function onDoSometingRequest(originId) { var requestData = $IN.data; var clientId = $IN.data.clientId; debug("Received request with parameters: " + requestData.toString()); var response = calculateSomeResoinse(); // Send the Backend-side calculated response to the requesting client: publishBroadcastToClient("doSometingResponse", [{"someKeyForTheresponse": response}], clientId); } function publishBroadcastToAllClients(typeDefinitionName, changeSetList) { publishBroadcastToClient(typeDefinitionName, changeSetList, null); } function publishBroadcastToClient(typeDefinitionName, changeSetList, clientId) { if(!changeSetList.isEmpty()) { var broadcastData = { "originId": uuid(), "typeDefinitionVersion": nowInMillis(), "typeDefinition": typeDefinitionName, "changeSet": changeSetList }; broadcastDatagram(broadcastData, clientId); } } .. .. index:: createDataSyncElement() Backend built-in function createDataSyncElement() function --------------------------------- It has the *typeDefinitionName* and the *data* parameter describing rows. *Function syntax* .. DataSyncRpElement createDataSyncElement(typeDefinitionName, data) Where the *typeDefinitionName* is a mandatory String, the *data* is a mandatory List of Map objects, and the function returns the appropriate DataSyncRpElement. .. code-block:: scolvoscript :caption: Example createDataSyncElement() function call in DataSync.scolvo Backend script's onDataSync event :linenos: function onDataSync(userId, deviceType) { debug("onDataSync " + userId + " deviceType: " + deviceType); // For a superUser only the MHUB is the available client type if (userId == "superUser") { return dataSyncByAdministrator(deviceType); } // Check user details to make decision about the sync content: var user = getUserById(userId); debug("Device type is: " + deviceType); if (user.role == "administrator") { return dataSyncForAdministrator(deviceType); } else if (user.role == "someCustomerSpecificRole") { return dataSyncForSomeCustomerSpecificRole(user); } warn("No dedicated DataSync case, returning empty data for user " + user.role); return []; } function dataSyncForAdministrator(deviceType) { debug("Creating data sync content for administrator"); // For an administrator role only the MHUB is the available client type if (deviceType == "MHUB") { return [ createDataSyncElement("user", getUsers()), ]; } return []; } function dataSyncForSomeCustomerSpecificRole(userDao) { debug("Creating data sync content for someCustomerSpecificRole"); return [ createDataSyncElement("example_table", getExampleRowsForUser(userDao.id)) ]; } .. .. index:: External communication functions External Communication functions ================================== This function group implements functionality for external communication. It supports: - *httpDownloadUrl* function downloading content from the given URL and saving the content to a file, - *httpPost* function sending POST request with json body or containing file requests, - *httpCall* function with generic type of request definition and security configuration possibilities, - *sendToDevices* function sending Firebase message, - *sendEmail* function sending email message. .. index:: httpDownloadUrl() Backend built-in function httpDownloadUrl() function --------------------------------- It downloads content from the given *url* to a file defined by *fileName* parameter (the *fileName* is taken as pattern). *Function syntax* .. String httpDownloadUrl(url, fileName) Where the *url* is given a mandatory String representing the URL of the desired location, the *fileName* is a mandatory String, defining the result file name template. Using this template a unique name is generated and returned as result. .. code-block:: scolvoscript :caption: Example httpDownloadUrl() function call :linenos: function getTheMoon(originId) { debug("Downloading moon ... "); var moonUrl = "https://spaceplace.nasa.gov/review/all-about-the-moon/the-moon-near-side.en.jpg"; var resultFile = httpDownloadUrl(moonUrl, "MyMoonPhoto.jpg"); debug("My Moon is under: " + resultFile); return resultFile; } .. .. index:: httpPost() Backend built-in function httpPost() function --------------------------------- This built-in function sends a POST Http request to the given *url*. *Function syntax* .. String httpPost(String url, Map headers, String jsonContent, Map bodyFileDescriptor) Where the *url* is given as String (mandatory String parameter), the *headers* parameters are merged to the request's header, and the content is sent as *jsonContent* String or as Map *bodyFileDescriptor* (one of these latter has to be defined, if both are given, then json string is sent). The result is the resonse body, it is returned as String. .. code-block:: scolvoscript :caption: Example httpPost() function call :linenos: function sendPostRequestWithAuthorizationHeader(originId) { debug("Sending post request ... "); var jsonObject = {"key": "value"}; var url = "https://eov8qe6o4c0adbw.m.pipedream.net"; var headers = {"Authorization": "Basic XYZ", "x": "y"}; var result = httpPost(url, headers, jsonObject.toString(), null); debug("The result is: " + result); return result; } .. .. index:: httpCall() Backend built-in function httpCall() function --------------------------------- This built-in function is a generic purpose function to send any kind of Http request, where many parameter can be specified. *Function syntax* .. HttpResponse httpCall(Map requestDescriptor) Where the *requestDescriptor* is the Map representation of the HttpRequest object, the result is a HttpResponse object (definitions of these objects are below). HttpRequest object attributes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * String *requestMethod* - default value is GET, other possible values: HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE, * String *url*, contains the targeted URL, * Map *headerParams* - all given parameters are put to request headers, * boolean *baseAuth* - defines if base authentication is used (an alternate solution to but the ready made Authorization header value to headerParams), * String *baseAuthUser* - in case of *baseAuth* is true, then the auth user is used when generating appropriate Base64 String, * String *baseAuthPw* - in case of *baseAuth* is true, then the auth password is used when generating appropriate Base64 String, * String *jsonData* - if given, then this content is sent as json body of the request, * Map *formData* - if *jsonData* is not given or null, then this content is sent as form data. HttpResponse object attributes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * *statusCode* int, containing the HTTP status code as integer, can be accessed by getStatusCode() call, * *data* Object, containing the response data, can be accessed using getData() call, .. code-block:: scolvoscript :caption: Example httpCall() function call :linenos: function sendPostRequestWithAuthorizationHeader(originId) { debug("Sending post request ... "); var jsonObject = {"key": "value"}; var request = { "requestMethod": "POST", "url": "https://mydream.net", "baseAuth": true, "baseAuthUser": "MyUser", "baseAuthPw": "MyPassword", "headerParams": { "Content-Type": "application/json" }, "jsonData": jsonObject.toString() }; var response = httpCall(request); debug("The result code is: " + response.getStatusCode()); debug("The result data is: " + response.getData()); return response; } .. .. index:: sendToDevices() Firebase related Backend built-in function sendToDevices() function --------------------------------- This built-in function sends a Firebase request with given parameters to the defined Firebase clients (defined by Firebase tokens). It requires the Firebase related configuration to be set. *Function syntax* .. void sendToDevices(String title, String body, Map data, List registrationTokens) Where the *title*, *body* and data are defining the message, the *registrationTokens* parameter defines target user audience. In case of any communication error a FirebaseErrorResultException is thrown describing the error cases. Hint: The *List getErrorDetails()*, or *String getMessage()* functions can be used to get error details from FirebaseErrorResultException instance. .. code-block:: scolvoscript :caption: Example sendToDevices() function call :linenos: function sendMessageToUsers(originId, tokens) { debug("Sending firebase message ... "); try { var data = { "key": "someValue" }; sendToDevices("My Important Message", "Dear User, Please do these important staps ...", data, tokens); debug("Firebase message has been sent successfully."); } catch (FirebaseErrorResultException e) { error("Error when sending message to firebase users: " + e.getMessage()); } } .. .. index:: sendEmail() Backend built-in function sendEmail() function --------------------------------- This built-in function sends an email message with the given parameters. It requies the email sending related configuration to be set. *Function syntax* .. boolean sendEmail(String from, String toAddressList, String ccAddressList, String subject, String content, List attachments) Where the *from* defines the sender email address in String, the *toAddressList* and *ccAddressList* are addresses in form of String (separated by coma for multi-address case), the *subject* and *content* are describing the message, and the *attachments* defines the pathes for the attached files (if there is any). It returns true is the sending is successful. .. code-block:: scolvoscript :caption: Example sendEmail() function call :linenos: function sendMessageToUsers(originId, addresses) { debug("Sending email message ... "); // example addreses content: "address1@mydomain.com, address2@mydomain.com" var attachments = ["/app/documents/stepsDescription.pdf"]; var result = sendEmail(getEnv("EMAIL_USERNAME"), addresses, null, "Important Information for MyDomain Users", "Message content ...", attachments); if (result) { debug("The message has been sent successfully."); } else { debug("The email message hasn't been sent."); } } .. .. index:: Document handling functions Document handling functions ================================== This function group implements functionality for Cloud handling, Local file handling and import/export related functions. It supports: **Cloud functions** - *documentGetUrl* function generating public URL for a content in a Cloud repository (requires appropriate Cloud repository configuration), - *documentPut* function uploading local content to the Cloud repository (requires appropriate Cloud repository configuration), - *documentDownload* function downloading content from the Cloud repository (requires appropriate Cloud repository configuration), **Filesystem functions** - *createDirectory* function creating a directory in local filesystem, - *listDirectory* function listing the content of a directory in the local filesystem, - *fileDelete* function deleting an entry (file or directory) from local fileystem, - *fileCopy* function copying an entry in the local filesystem, - *fileMove* function moving an entry in the local filesystem, **Export/import functions** - *writeFile* function writing content to a file, - *fileToString* function reading the content of a file, - *writeCsvFile* function writing data to CSV format, - *readCsvFile* function reading CSV file to data, - *readExcelFile* function reading Excel file to data. .. index:: documentGetUrl() Backend built-in function documentGetUrl() function --------------------------------- This built-in function gets a public URL (containing autentication) to the given resource path in the configured Cloud repository. (It requires a configured Cloud repository.) *Function syntax* .. String documentGetUrl(String documentKey) Where the *documentKey* is the path of an existing document in the Cloud repository. It return the URL accessing the document in Http GET reuest. .. code-block:: scolvoscript :caption: Example documentGetUrl() function call :linenos: function uploadCsvFileToCloud(fileName, cloudRelativePath, csvHeaders, content) { var filePath = writeCsvFile(fileName, csvHeaders, content, getCsvFormat()); debug("CsvFile is created on path: " + filePath); documentPut(filePath, cloudRelativePath); var downloadUrl = documentGetUrl(cloudRelativePath); debug("CsvFile public URL is: " + downloadUrl); return downloadUrl; } .. .. index:: documentPut() Backend built-in function documentPut() function --------------------------------- This built-in function uploads a file to the configured Cloud repository. (It requires a configured Cloud repository.) *Function syntax* .. void documentPut(String sourcePath, String targetPath) Where the *sourcePath* is the path of an existing document in the local filesystem and the *targetPath* is a path to be created in the Cloud repository. .. code-block:: scolvoscript :caption: Example documentPut() function call :linenos: function uploadCsvFileToCloud(fileNamePattern, cloudRelativePath, csvHeaders, content) { var filePath = writeCsvFile(fileNamePattern, csvHeaders, content, getCsvFormat()); debug("CsvFile is created on path: " + filePath); documentPut(filePath, cloudRelativePath); var downloadUrl = documentGetUrl(cloudRelativePath); debug("CsvFile public URL is: " + downloadUrl); return downloadUrl; } .. .. index:: documentDownload() Backend built-in function documentDownload() function --------------------------------- This built-in function downloads an entry from the configured Cloud repository. (It requires a configured Cloud repository.) *Function syntax* .. String documentDownload(String sourcePath, String targetPathPattern) Where the *sourcePath* is the path of an existing document in the CloudRepository and the *targetPathPattern* is a path pattern int the local filesystem. It returns the full path (not the same as given in *targetPathPattern* parameter) to the downloaded file. .. code-block:: scolvoscript :caption: Example documentDownload() function call :linenos: function downloadCsvFileFromCloud(cloudRelativePath, fileNamePattern) { var filePath = documentDownload(cloudRelativePath, fileNamePattern); debug("CsvFile is created on path: " + filePath); return filePath; } .. .. index:: createDirectory() Backend built-in function createDirectory() function --------------------------------- This built-in function creates a directory in the local filesystem. The actual implementation can create only the last directory, the containing path must exist. *Function syntax* .. boolean createDirectory(String directoryPath) Where the *directoryPath* is the path of the directory to be created. It returns true in only case when the directory is created by this call. .. code-block:: scolvoscript :caption: Example createDirectory() function call :linenos: function createSubDirectory(containingDirectory, subDirectory) { var targetPath = directory + "/" + subDirectory; if (createDirectory(targetPath)) { return targetPath; } return null; } .. .. index:: listDirectory() Backend built-in function listDirectory() function --------------------------------- This built-in function lists an existing directory in the local filesystem. *Function syntax* .. Map> listDirectory(String directoryPath) Where the *directoryPath* is the path of the directory to be listed. It returns with the content of the directory with a descriptor containg name, size, type, absolute path and last modification time (see the example below). .. code-block:: scolvoscript :caption: Example listDirectory() function call :linenos: function listDirectoryContent(directoryPath) { var content = listDirectory(directoryPath); debug("The result is: " + content); content.keySet().each(function(fileName){ debug("----------------------------------"); debug(" Actual entry is: " + fileName); var descriptor = content.get(fileName); debug(" Name is: " + descriptor.get("name")); debug(" Type is: " + descriptor.get("fileType")); debug(" Size (in Bytes) is: " + descriptor.get("size")); debug(" Absolute path is: " + descriptor.get("absolutePath")); debug(" Last modified is: " + dateToString(descriptor.get("lastModified"), "yyyy.MM.dd. HH:mm")); }); return content; } .. .. index:: fileDelete() Backend built-in function fileDelete() function --------------------------------- This built-in function deletes the given path and returns the status of the operation (true if deleted, false oterwise). *Function syntax* .. boolean fileDelete(String path) Where the *path* is the path of the local filestem entry to be deleted. If the given *path* is a non-empty directory, then it is deleted with its child entries. .. code-block:: scolvoscript :caption: Example fileDelete() function call :linenos: function deleteDirectoryContent(directoryPath) { debug("Deleting directory with its content: " + directoryPath); return fileDelete(directoryPath); } .. .. index:: fileCopy() Backend built-in function fileCopy() function --------------------------------- This built-in function creates a copy of the source file to the given path. *Function syntax* .. void fileCopy(String sorcePath, String targetPath) Where the *sourcePath* is an existing path in the filesystem, and the *targetPath* is the path where the file copy has to be created. It is possible to copy a simple file entry or a complete directory. .. code-block:: scolvoscript :caption: Example fileCopy() function call :linenos: function backupDirectory(directoryPath, backupDirectoryPath) { debug("Creating backup of directory: " + directoryPath); var content = listDirectory(directoryPath); content.keySet().each(function(fileName){ var descriptor = content.get(fileName); var sourcePath = descriptor.get("absolutePath"); var targetPath = backupDirectoryPath + "/" + descriptor.get("name"); fileCopy(sourcePath, targetPath); }); } .. .. index:: fileMove() Backend built-in function fileMove() function --------------------------------- This built-in function moves an existing file to a new path. *Function syntax* .. void fileMove(String sorcePath, String targetPath) Where the *sourcePath* is an existing path in the filesystem, and the *targetPath* is the new path of the entry. .. code-block:: scolvoscript :caption: Example fileMove() function call :linenos: function downloadFileFromCloud(cloudRelativePath, targetDirectory, fileName) { var filePath = documentDownload(cloudRelativePath, fileName); debug("File is created on path: " + filePath); var targetPath = targetDirectory + "/" + fileName; fileMove(filePath, targetPath) debug("File is moved to path: " + targetPath); return targetPath; } .. .. index:: writeFile() Backend built-in function writeFile() function --------------------------------- This built-in function creates a file with the given content. *Function syntax* .. String writeFile(String fileNamePattern, String content) Where the *fileNamePattern* is the file name pattern of the created file, and the *content* is a String to be written to the file. It retuns the fupp path of the created file. .. code-block:: scolvoscript :caption: Example writeFile() function call :linenos: function createMonthlyReport(type, month, content) { var fileNamePattern = "Report_" + type + "_" + month + ".txt"; var resultPath = writeFile(fileNamePattern, content); debug("Report File is created at: " + resultPath); return resultPath; } .. .. index:: fileToString() Backend built-in function fileToString() function --------------------------------- This built-in function reads a file content and returns it as String. *Function syntax* .. String fileToString(String filePath) Where the *filePath* is the prat of the file to be read. .. code-block:: scolvoscript :caption: Example fileToString() function call :linenos: function readInputFile(fileName) { var importFilePath = "/import/" + fileName; var content = fileToString(importFilePath); if(content != null) { debug("Read content size: " + content.size()); } else { debug("No content returned from file " + importFilePath); } return content; } .. .. index:: writeCsvFile() Backend built-in function writeCsvFile() function --------------------------------- This function writes the given content using header columns and formatting parameters to a CSV file. The path of the created file is returned. *Function syntax* .. String writeCsvFile(String namePattern, List headerColumns, List> data, Map csvFormattingParameters) Where: - *namePattern* is a String mandatory parameter, it is used as a basis for filename construction, - *headerColumns* is a List mandatory parameter, a not empty list of the headers, - *data* is a List> list of content lines (mandatory parameter), a non-empty list of lines, - *csvFormattingParameters* is a Map (mandatory parameter), see below description for keys and values. - it returns the path of the created file, - it throws FunctionInvokeException in case of errors. Details of valid CSV formatting parameters: - The parameters given in Map format, - *format* - String, name of the CSV format, if not given, then "Default" is used, (valid values are: Default, Excel, InformixUnload, InformixUnloadCsv, MongoDBCsv, MongoDBTsv, MySQL, Oracle, PostgreSQLCsv, PostgreSQLText, RFC4180, TDF), it is used as a basis of other parameters, - *delimiter* - String, the first character taken as delimiter character, - *quote* - String, the first character taken as quote character, - *nullString* - String, it is set as the null-string value for the formatter, - *skipHeaderRecord* - boolean, its value set to skipHeaderRecord of the formatter, - *recordSeparator* - String, its value set as record separator, - *charset* - String, its value is used to create a charset, if not given, then UTF-8 is used. .. code-block:: scolvoscript :caption: Example writeCsvFile() function call :linenos: function getCsvFormat() { var format = { "delimiter": ";", "quote": null, "nullString": "", "skipHeaderRecord": false, "recordSeparator": "\r\n", "charset": "UTF-8", }; return format; } function exportDataToCsv() { var csvHeaders = ["StoreDevice_Code", "StoreDevice_DeviceTypeName"]; var content = []; var storeDevices = getStoreDevicesByStatus("active"); storeDevices.each(function(storeDevice) { content.add([storeDevice.deviceCode, storeDevice.deviceTypeName]); }); var reportName = "Data_" + dateToString(nowInMillis(), "yyyyMMdd_HHmm") + ".csv"; var filePath = writeCsvFile(reportName, csvHeaders, content, getCsvFormat()); debug("CsvFile is created on path: " + filePath); var targetPath = "/export/" + fileName; fileMove(filePath, targetPath); return targetPath; } .. .. index:: readCsvFile() Backend built-in function readCsvFile() function --------------------------------- This function reads the content of the given CSV file to structured List> format. *Function syntax* .. List> readCsvFile(String pathToFile, List headerColumns, Map csvFormattingParameters) Where: - *pathToFile* - is a String (mandatory parameter), - *headerColumns* - List (mandatory parameter), a not empty list of the headers, - *csvFormatParameters* - Map (mandatory parameter), see below the description of keys and values, - it returns the content in form of List> according to the specified format, - it throws FunctionInvokeException in case of errors. .. code-block:: scolvoscript :caption: Example readCsvFile() function call :linenos: function getReadCsvFormat() { var format = { "delimiter": ";", "quote": null, "nullString": "", "skipHeaderRecord": true, "recordSeparator": "\r\n", "charset": "Cp1250", }; return format; } function importDataFromCsv() { debug("Importing data ...."); var filePath = documentDownload("/import/data.csv", uuid()); var importHeaders = ["Name", "ID", "Size", "Activity_ID", "Exporter"]; var parsedData = readCsvFile(filePath, importHeaders, getReadCsvFormat()); fileDelete(filePath); return parsedData; } .. .. index:: readExcelFile() Backend built-in function readExcelFile() function --------------------------------- This function reads the content of the given Excel file (.xls or .xlsx file) to structured format. *Function syntax* .. Map>> readExcelFile(String filePath, int numOfColumns) Where: - *filePath* - mandatory parameter String, - *numOfColumns* - BigInteger mandatory parameter, non-negative number, if 0 is given, then every sheet is checked for its max column, - it returns the sheets defined by lines and cells in form of Map>>, - it throws FunctionValidationException for invalid parameters, and FunctionInvokeException for processing errors. .. code-block:: scolvoscript :caption: Example readExcelFile() function call :linenos: function readImportFromFile(filePath, sheetName) { var result = readExcelFile(filePath, 3); var sheet = result.get(sheetName); var fullContent = []; sheet.each(function(line) { var content = "["; line.each(function(cell) { content = content + "'" + cell + "', "; }); content = content + "]"; fullContent.add(content); }); return fullContent; } .. .. index:: Reporting repository functions Reporting repository functions ================================== This function group implements functionality for Reporting repository handling. It supports: - *downloadReport* function to download specific report from Reporting repository, .. index:: downloadReport() Backend built-in function downloadReport() function --------------------------------- This function supports report file downloading from configured Reporting repository. The hendling of the download is asynchronus, in case of success a successTrigger is executed, in case of error the given errorTrigger is called. *Function syntax* .. void downloadReport(String downloadId, String reportUrl, String reportFileName, String successTrigger, String errorTrigger, Map additionalParameters) Where: - *downloadId* is a String, mandatory parameter, - *reportUrl* is a String, mandatory parameter, - *reportFileName* is a String, filename base string used when storing locally the downloaded file, - *successTrigger* is a String, mandatory parameter, the name of the function to be invoked in case of success, - *errorTrigger* is a String, optional parameter, the name of the function to be invoked in case of error, - *additionalParameters* is a Map, optional parameter, parameters that have to be added to trigger parameters Trigger parameters are in case of success (these are put to $IN.data map): - *id* - the corresponding download id, - *filePath* - the path of the downloaded file in local filesystem, - additional keys and values from additionalParameters map. Trigger parameters are in case of error (these are put to $IN.data map): - *id* - the corresponding download id, - *errorCode* - the code of the error in form of String, - *errorMessage* - the error message, - additional keys and values from additionalParameters map. .. code-block:: scolvoscript :caption: Example downloadReport() function call :linenos: function onMontlyTodoReportDownloadSuccess(originId) { debug("The id of the Report download is: '" + $IN.data.id + "' The path of the downloaded file: '" + $IN.data.filePath + "'"); debug("The downloadedFile for Store '" + $IN.data.storeName + "' is at " + $IN.data.filePath); // Do the logic, e.g. send an email var deleteResult = fileDelete($IN.data.filePath); debug("Report file has been deleted with result: " + deleteResult); } function onMontlyTodoReportDownloadError(originId) { error("The MontlyTodoReport download has been failed with id: '" + $IN.data.id + "' The error is: " + $IN.data.errorCode + " - " + $IN.data.errorMessage); } function sendMonthlyTodoReports(dueMonth) { debug("Sending Monthly to-be-done tasks reports about previous month ..."); var users = getStoreLeaderUsersWithStore(); users.each(function(user) { info("Store: '" + user.storeId + "', Email: '" + user.email + "'"); var reportUrl = "https://something/report/monthlyreport/" + user.storeId; var downloadId = uuid(); var additionalParams = { "email": user.email, "storeName": user.storeName, "name": user.name, "dueMonth": dueMonth }; downloadReport(downloadId, reportUrl, "UserReport_" + user.email, "MontlyTodoReportDownloadSuccess", "MontlyTodoReportDownloadError", additionalParams); debug("Download MontlyTodoReport request is sent for store '" + use.storeId + "' ..."); }); } .. .. index:: Misc functions Misc functions ================================== This function group implements a set of utility functions. It supports: - *getEnv* function returning environment variables, - *getDictionaryValue* function reading backend dictionary values, .. index:: getEnv() Backend built-in function getEnv() function --------------------------------- This function retruns the value of the appropriate environment variable defined by the *key* parameter. *Function syntax* .. String getEnv(String key) .. code-block:: scolvoscript :caption: Example getEnv() function call :linenos: function sendMessageToUsers(originId, addresses) { debug("Sending email message ... "); // example addreses content: "address1@mydomain.com, address2@mydomain.com" var attachments = ["/app/documents/stepsDescription.pdf"]; var result = sendEmail(getEnv("EMAIL_USERNAME"), addresses, null, "Important Information for MyDomain Users", "Message content ...", attachments); if (result) { debug("The message has been sent successfully."); } else { debug("The email message hasn't been sent."); } } .. .. index:: getDictionaryValue() Backend built-in function getDictionaryValue() function --------------------------------- This function retruns the value of the appropriate dictionary key using the specified locale from backend dictionary files (backend_dictionary_*.properties). If the dictionary is not available, then the backend's default language (defined by DEFAULT_LANGUAGE env variable) is used to resolve the value. If the requested key is not defined, then a null value is returned. *Function syntax* .. String getDictionaryValue(String key, String locale) The function has the following parameters: - *key* - String, mandatory parameter, - *locale* - String mandatory parameter. .. code-block:: scolvoscript :caption: Example getDictionaryValue() function call :linenos: function resolveActivityStatusForLocale(status, locale) { return getDictionaryValue(status + "_name", locale); } ..