Skip to content
Web

Users & Sessions

Users

Permissions

AMI has its own way of doing permission control over different groups of users so that certain windows are only visible to users with entitlements. Suppose we have two windows named Restricted and Everyone. The Restricted window should NOT be visible to the users whose role is NOT Admin. The following screenshot shows how to set up such a scenario.

  1. Go to Dashboard -> Custom Callbacks

  2. Go to onStartup tab and enter the following AMI script commands:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    string role = session.getProperty("ROLE");
    if (role != "Admin"){
      for (window w: session.getWindows()){
        if (w.getName()=="Restricted"){
          w.setType("HIDDEN");
          w.minimize();
        }
      }
    }
    
  3. Hit Submit

Now the users should be able to see different windows based on their entitlements.

Sessions

Both the AmiWeb and AmiCenter have and manage sessions. Sessions are uniquely identified by a unique session identifier(_SESSIONID).

AmiWebSession

An AmiWebSession is created every time a user logs in to the frontend dashboard. The same user name can have multiple logins and a login can have multiple sessions. The below ERD(Entity Relation Diagram) is created to describe the relationship:

(1). One username can have multiple logins:
A user logins into a dashboard with two different browsers. We will see two login records,uniquely identified by __LOGINID, under the same username:

(2). One login can have multiple sessions: By default each login can have one session. This can be changed by configuring the property: ami.web.default.MAXSESSIONS After updating the max sessions, if we click Account->Start New Session we could create a new session under the same login.

Headless sessions

Setup

A headless session is a session that no single user claims ownership of. To create a headless session, edit your headless.txt in amione/data/ which by default contains the following line:

#headless1|headlessdemo|2000x1000|ISDEV=true
  1. headless1

    • Name of the session
  2. headlessdemo

    • Username of the headless session
  3. 2000x1000

    • Screen resolution in width x height of the session
  4. ISDEV=true

    • Permissions of the session

Configure the details accordingly.

Ownership

Before any user claims the ownership of a headless session, the __LOGINID for the headless session will be null.

A user can claim ownership of a headless session by going to Account->Take Ownership of Headless Session -> \<headless session name>

After ownership is taken, this headless session will be tied to the current login.

Likewise, the user can release the ownership of the headless session by clicking Account->Release Ownership of Headless Session.

AmiCenterSessions

Just like the notion of AmiWebSession, Ami Center also has the notion of session. One can see what sessions currently exist in the center by typing SHOW SESSIONS in the DB console or frontend shell tool.

AmiCenterSession Composition


Typically, there are 4 different types of AmiCenterSession:

  1. __SYSTEM is like the master session, sitting on top of the session hierarchy.

  2. __RTFEED is another session that manages all the real time feeds.

  3. __SCHEDULER sessions are sessions associated with timers. Each timer has one unique session associated with it.

  4. Your DB console terminal or frontend shell tool also has one session associated with it.

Managing sessions with f1 console commands

Sessions can also be managed through the f1 console port. By default, f1.console.port=3285

In this section we'll review the commands available:

amiWebServer.showLogins()

Show all logins

1
2
3
4
5
6
amiWebServer.showLogins()
 +----------+--------------------------+---------------------+--------+
 |__USERNAME|__LOGINID                 |__LOGINTIME(GMT)     |Sessions|
 +----------+--------------------------+---------------------+--------+
 |demo      |QIYSASDnM8MW7c0MLH3FEK3jKk|20231108 03:22:45.830|1       |
 +----------+--------------------------+---------------------+--------+
amiWebServer.showSessions()

Show all sessions

amiWebServer.showSessions()

amiWebServer.killSession(String sessionId)

Kill a user session

amiWebServer.killSession("xbqfQ4mmKxODw8f0jz2c")
 killed
amiWebServer.createHeadlessSession(String sessionName, String username, String resolution, String attributes)

Creates a headless session, resolution is in format widthXheight, eg 1000x2000, attributes in a comma delimited list

amiWebServer.createHeadlessSession("headless1","headlessdemo", "2000x1000","ISDEV=true")
 headless session created and enabled
amiWebServer.deleteHeadlessSession(String sessionName)

Delete a headless session

amiWebServer.deleteHeadlessSession("headless1")
 headless session deleted
amiWebServer.describeHeadlessSession(String sessionName)

Print the headless session details as it is saved in headless.txt

amiWebServer.describeHeadlessSession("headless1")
 headless1|headlessdemo|2000x1000|ISDEV=true
amiWebServer.disableHeadlessSession(String name)

Disables a headless session

amiWebServer.disableHeadlessSession("headless1")
 headless session disabled
amiWebServer.enableHeadlessSession(String sessionName)

Enable a headless session

amiWebServer.enableHeadlessSession("headless1")
 headless session enabled
amiWebServer.killLogin(String uid)

Kill user login

amiWebServer.killLogin("vBduBdZzUrjjmsONMhV8nkLiqh")
 killed user login
amiWebServer.showPanels(String sessionId)

Show all panels

1
2
3
4
5
6
7
amiWebServer.showPanels("xbqfQ4mmKxODw8f0jz2c")
 +--------------------+-------------+-------+-------+-----+------+---------+
 |Structure           |Type         |PanelId|Visible|Width|Height|Transient|
 +--------------------+-------------+-------+-------+-----+------+---------+
 |Desktop - 3forge AMI|Main Window  !null   |true   |1920 |911   !null     |
 | Inner Desktop      |Inner Desktop!null   |true   |1920 |883   !null     |
 +--------------------+-------------+-------+-------+-----+------+---------+
amiWebServer.exec(String sessionId, String script)

Execute amiscript

amiWebServer.exec("2un2sl88hTcPuDoPhxk9","round(2.3)")
2

Automated Report Generation (Headless)

Below are the steps for automatically generating reports and sharing them by sending an email, sending to an SFTP server, and saving to a filesystem.

Note that before starting AMI you will need to configure your headless.txt in amione/data/ to create a headless session:

headless1|headlessdemo|2000x1000|ISDEV=true

To send reports via email, you will need to configure your AMI instance for email compatibility. Configure your local.properties file with the following properties:

1
2
3
4
email.client.host=<SMTP_MAIL_HOST>;
email.client.port=<MAIL_PORT>;
email.client.username=<Sender_username_email>;
email.client.password=<Sender_password_token>;

Note

Different email providers have different requirements. Ensure you have configured your email to use SMTP correctly before using it in AMI.

Create the report

The PdfBuilder can be used to construct pdf documents, collating text and images together. First, go to Dashboard > Data Modeller then right click on the background and select "Add Datamodel", then put in the relevant pdf logic. Below is an example of a pdf with two pages, the first page has some text and a chart from the layout, the second just has text.

{
  PdfBuilder pdb = new PdfBuilder(); 

  // Configuring page settings
  pdb.setPageMargin(0.25,1,0.25,1,0,0);
  pdb.setFont(".14 normal #ffffff");
  pdb.setPageBackground("#073763");
  pdb.setHorizontalAlignment("LEFT");

  // Adding text and images
  Binary img = mychart.toImagePng(1000,1000,true);
  pdb.appendText("Hello World");
  pdb.appendImage(img,100);
  pdb.appendPageBreak();
  pdb.appendText("Some text on the second page!");

  Binary file = pdb.build();
}

Once generated, the report can be saved and distributed in a number of ways detailed below.

Email

To send via email (given email properties mentioned above were set):

session.sendEmailSync("test@gmail.com", new List("test@gmail.com"), "Report", false, "Body", new List("report.pdf"), new List(pdf), null, null);

Saved to local file system

The pdf can also be saved to amione/reports/, in this case titled with the date it is generated on:

1
2
3
4
FileSystem fs = session.getFileSystem();
String dt = formatDate(timestamp(), "yyyy-MM-dd", "UTC");
String saveFile = "reports/charts ${dt}.pdf";
fs.writeBinaryFile(saveFile, pdf, false);

SFTP

The report can also be shared via a SFTP connection. First, go to Dashboard -> Data Modeler -> Attach Datasource...; then select SFTP from the datasources, and input your sftp server details. Click Add Datasource. Once successful, you can upload files to your remote server like so:

use ds=ServerSFTP insert `reports/report.pdf` from select pdf as text;

The above line will upload the pdf to the remote server at the path reports/report.pdf.

Embed Charts in Email Body (No PDF)

Charts can also be embedded directly into the body of an email using HTML, rather than as a pdf attachment.

You will need the image of the chart, the binary information of which is directly passed into the attachment parameter of sendEmail(), and embed that information into HTML which is then passed as the body of the email.

1
2
3
4
ChartPanel vBar = layout.getPanel("vBar");
Binary vBarImg = vBar.toImagePng(1000,1000,true);
String htmlStr = "<img src=\"cid:vBarImg.png\" alt=\"Vertical Bar Graph\" width=\"450\" height=\"450\">";
session.sendEmail("test@gmail.com",new List("test@gmail.com"),"Report", true, "${htmlStr}",new List("vBarImg.png"), new List(vBarImg),null,null);

Ensure that the isHtml parameter is set to true. Then, configure the HTML content of the email body parameter to correspond to the embedded chart (in this example this is the string variable htmlStr).

The filename given to the chart on generation is used as the cid in the <img src> tag of the email body.

Embed Tables in Email Body (No PDF)

Tables can also be directly embedded into the body of an email. Create a custom method that converts the table into an HTML representation which can then be used in the body of an email.

String createTableElement(Table t) {
    String tableHtml = "<tr style=\"background-color: #3E4B4F;color:#FFFFFF\">";
    for (String colName: t.getColumnNames()) {
        tableHtml += "<th style=\"width:110px; height:20px; border: 1px solid;\"> ${colName} </th>";
    }
    tableHtml += "</tr>";

    for (Row r: t.getRows()){
        tableHtml += "<tr>";
        for (int i = 0; i < r.size(); i++) {
        String cell = r.getValueAt(i);
        tableHtml += "<td style=\" background-color: #3A3A3A;color:#FFFFFF;width:110px; height:20px; border: 1px solid;\"> ${cell} </td>";
        }
        tableHtml += "</tr>";
    }
    return tableHtml;
    };

Then call this method on the table you wish to embed:

1
2
3
4
5
TablePanel tab = layout.getPanel("Opp");
Table t = tab.asFormattedTable(true,true,true,true,false);
String table = createTableElement(t); //HTML conversion using our custom method
String htmlStr = "<table style=\"border: 1px solid;background-color: #D6EEEE;\"> ${table} </table> <img src=\"cid:vBarImg.png\" alt=\"Vertical Bar Graph\" width=\"450\" height=\"450\">";
session.sendEmail("test@gmail.com",new List("test@gmail.com"),"Report", true, "${htmlStr}",new List("vBarImg.png"), new List(vBarImg),null,null);

In this example, both a table and chart are being embedded in the email body, represented by the string variable htmlStr.

Automate the datamodel

To automate the datamodel (and pdf generation) we can use the Timer interface, this can be accessed by clicking the Timers (0) button in the bottom right corner of the Edit Datamodel window.

Any standard crontab timer can then be used. For example, 0 */2 * * * * UTC runs every two minutes. Inputting a time like 14:30:00 would make it run every day at 14:30. Click Test and make sure that the upcoming Runtimes are expected.

Once you've configured everything correctly, submit the timer, finish the datamodel, and save the layout.

Creating a headless session

We now have a layout with a datamodel which creates and sends a pdf. However, this is tied to a user session, so when the user logs out the reports will stop generating. To make sure our reports continue to run we'll need to use a headless session.

First, edit headless.txt in amione/data/ as described at the start of this guide. Then start AMI and login as admin or dev user. Under Account -> Take ownership of headless session, select the headless session you set up in the headless.txt file.

Open the layout you made for constructing the report, then select Account -> Release ownership of this headless session.

This session will now continuously run and keep sending reports.