Skip to content

Commit

Permalink
chore: fix a merge conflict
Browse files Browse the repository at this point in the history
  • Loading branch information
krishanthisera committed Sep 17, 2023
2 parents 7f58a59 + c94e599 commit 9c3e35c
Show file tree
Hide file tree
Showing 8 changed files with 597 additions and 4 deletions.
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v16.18.1
2 changes: 1 addition & 1 deletion .prettierrs.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"useTabs": true,
"overrides": [
{
"files": [".*", "*.json", "*.md", "*.toml", "*.yml"],
"files": [".*", "*.json", "*.md", "*.toml", "*.yml", "*.astro"],
"options": {
"useTabs": false
}
Expand Down
216 changes: 216 additions & 0 deletions src/content/blog/asterisk-gateway-interface.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
---
title: "Asterisk Gateway Interface"
description: "In this article, we will discuss the basics of the Asterisk Gateway Interface (AGI)."
pubDate: "May 10 2018"
heroImage: 'https://bizkt.imgix.net/post/asterisk-gateway-interface/asterisk_gateway_interface.png'
badge: "RETRO"
---

> The content of this article is migrated from the old blog post, so the information might be subject to updates.
See the Code snippets related to this article [here](https://gist.github.com/krishanthisera/177f2646443f3b56af907a0ab68ebbea).

## 1. What is the Asterisk Gateway Interface?

In simple terms, Asterisk Gateway Interface or AGI is a language-independent API that allows programmers to control the call flow on their Asterisk PBXs.

Asterisk offers more than just its own dial-plan to control call flow or call logic. You may use any of the following:

- Dialplan
- Asterisk Manager Interface (AMI)
- Asterisk Gateway Interface (AGI)

### Dialplan

Dial plan is Asterisk's native mechanism for handling the call logics. It's fast, easy to learn, and efficient. However, this configuration script is closer to assembly programming. A significant drawback of the Asterisk Dialplan is its lack of support for standard procedural languages, for instance, like creating loops.

In this article we will focus on AGI. However, it's worth noting that we need the Dialplan to initiate the AGI scripts.

### Asterisk Manager Interface (AMI)

Imagine having a remote control for your Asterisk PBX. That is AMI. It's more sophisticated compared to the Dialplan. Essentially, you can control your PBX using a TCP socket.

However, be cautious as this comes with some security concerns.

### Asterisk Gateway Interface (AGI)

If you compare AMI and Dialplan with AGI, AGI lies between them. AGI isn't entirely independent; it requires the support of the Dialplan. Moreover, AGI allows you to use your preferred language for scripting. In this tutorial, we'll be using Perl.

Before we dig deeper, if your PBX system solely handles outbound calls, AGI isn't for you, as AGI is designed primarily for inbound call handling.

There are four types of AGIs:

- **Standard AGI**: The simplest form, using standard inputs (STDIN) and outputs (STDOUT) to communicate with the PBX.
- **Dead AGI**: Handles call logic after a call has been hung up. Some AGI commands aren't available in this mode.
- **Fast AGI**: Allows you to offload AGI processing to another server, using TCP sockets. It offers all features found in Standard AGI.
- **EAGI**: For developers who need to communicate beyond the standard inputs and outputs, particularly if they need to access the media channel.

## 2. Scenario Discussion

We have two SIP peers named Peter and Bob. They should be able to call each other. If one is unavailable, the caller should have the option to leave a voicemail. The recipient can later access and listen to this voicemail by dialing an extension with '*' (e.g.,*101).

### Configuration

1. **SIP Peers**

```bash
sip.conf
[peter]
type=friend
secret=123
host=dynamic
allow=alaw,ulaw
context=users

[bob]
type=friend
secret=123
host=dynamic
allow=alaw,ulaw
context=users
```

2. **Dialplan Configuration**

```bash
extensions.conf
[users]
exten => _[*0-9]X.,1,NoOp("Dialing AGI")
same => n,AGI(dialplan.pl,${EXTEN})
```

3. **Voicemail Configuration**

```bash
voicemail.conf
[sales]
101 => 123,Bob's Mailbox,[email protected]
102 => 321,Peter's Mailbox,[email protected]
```

After configuring, reload your settings:

```bash
rasterisk
```

```bash
> sip reload
> sip show peers
> dialplan reload
> voicemail reload
> voicemail show users
```

### Perl Script for AGI

```perl
#!/usr/bin/perl
# Asterisk Dialplan Script
# This script handles dialplan routing for Asterisk.
use warnings;
use strict;

# Import necessary Perl modules
use Asterisk::AGI;

# Retrieve the dialed extension from the command line argument
our $DPLAN_EXTEN = $ARGV[0];

# Check if the dialed extension starts with an asterisk (*)
# If so, it's a voicemail box; otherwise, proceed with standard routing
if ($DPLAN_EXTEN =~ m/^\*/) {
vm_box();
} else {
main();
}

# Define call routes between two peers: Bob and Peter
sub main {
my %EXTEN_CONF = (
'101' => {
'CHAN' => 'SIP',
'PEER' => 'bob',
'MAXWAIT' => 5,
'VM_CONTEXT' => 'sales',
},
'102' => {
'CHAN' => 'SIP',
'PEER' => 'peter',
'MAXWAIT' => 5,
'VM_CONTEXT' => 'sales',
},
);

my $AGI = new Asterisk::AGI;
$AGI->exec('Dial', "$EXTEN_CONF{$DPLAN_EXTEN}{'CHAN'}/$EXTEN_CONF{$DPLAN_EXTEN}{'PEER'},$EXTEN_CONF{$DPLAN_EXTEN}{'MAXWAIT'}");
$AGI->exec('VoiceMail', "$DPLAN_EXTEN\@$EXTEN_CONF{$DPLAN_EXTEN}{'VM_CONTEXT'}");
$AGI->hangup();
}

# Listen to the Voice Mails
sub vm_box {
my %VM_CONF = (
'*101' => {
'VM_BOX' => '101',
'VM_CONTEXT' => 'sales',
},
'*102' => {
'VM_BOX' => '102',
'VM_CONTEXT' => 'sales',
},
);

my $AGI = new Asterisk::AGI;
$AGI->exec('VoiceMailMain', "$VM_CONF{$DPLAN_EXTEN}{VM_BOX}\@$VM_CONF{$DPLAN_EXTEN}{VM_CONTEXT}");
$AGI->hangup();
}
```

The provided Perl script uses the `Asterisk::AGI`` module. This module allows for interaction with the Asterisk Gateway Interface. The script contains logic for routing calls and managing voicemail.

#### Setting Up the Perl Environment

Install the necessary build tools:

```bash
apt-get install build-essential
```

Access the CPAN shell:

```bash
cpan
```

Inside the CPAN shell, install the `Asterisk::AGI` module:

```bash
install Asterisk::AGI
```

(Exit the CPAN shell once the installation is complete.)

Setting up the AGI Script:

```bash
# Place the AGI script inside the Asterisk's agi-bin directory by navigating to:
cd /var/lib/asterisk/agi-bin

# Ensure the script has the correct ownership and execute permissions,
# Change the script's ownership to the Asterisk user:
chown asterisk:asterisk dialplan.pl

# Grant execute permissions to the script:
chmod u+x dialplan.pl
```

For detailed information on Asterisk Dialplan applications and their usage, refer to the Asterisk CLI or visit [voip-info.org](https://www.voip-info.org).

## Additional Resources

For further details and related code snippets, check out the Gist provided [here](https://gist.github.com/krishanthisera/177f2646443f3b56af907a0ab68ebbea).

---

Congratulations! Your Asterisk Gateway Interface is now set up and ready to use. Enjoy!
104 changes: 104 additions & 0 deletions src/content/blog/database_transactions_perl.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
---
title: "Database Transactions with 🐪 Perl"
description: "In this article, we will discuss about Database transactions and we how we can implement Database transactions in Perl."
pubDate: "May 15 2018"
heroImage: 'https://bizkt.imgix.net/posts/perl-db-transactions/perl_db_transactions.jpeg'
badge: "RETRO"
---

> The content of this article is migrated from the old blog post, so the information might be subject to updates.
To understand what a database transaction is, let's look at a simple bank withdrawal and deposit scenario. Imagine you have two bank accounts, A and B, and you want to withdraw some amount from account A and deposit it into account B.

What happens if you can't withdraw money from account A? Then the deposit into account B won't proceed. Similarly, if you can't deposit the money into account B, you'd need to deposit it back into account A (i.e., a rollback).

In the context of a database, a transaction refers to a sequence of jobs that are supposed to run as a unit; it either completes fully or not at all. For instance, in the following example, we have three database queries that should execute together. If the first query inserts data successfully, the second one should update a table, and the third one should delete an entry. If any of them fails for any reason, everything should revert to its initial state. The idea behind transactions is to ensure data integrity no matter what happens.

There are four properties of database transactions, known as ACID:

- **Atomic**: If one part of the transaction fails, the entire transaction fails, and the database state remains unchanged.
- **Consistency**: Only valid changes are accepted. If changes are invalid, the system reverts to the previous state.
- **Isolation**: Until a transaction is committed, its changes are not visible to other transactions.
- **Durability**: Once a valid change is committed, it remains in place.

You can find a detailed explanation about ACID [here](https://www.databricks.com/glossary/acid-transactions).

## Perl Example

First, let's install the necessary Perl and MySQL dependencies on a Debian system:

```bash
apt-get install libdbd-mysql-perl
cpan
> install DBI
```

Now, let's dive into our Perl script. I've used a hash to store the MySQL database configuration and another hash for connection attributes. You can also combine these hashes based on your needs.

**⚠️ Never commit sensitive information, such as database passwords, in version control systems. Seek alternative methods for secure storage.**

```perl
#!/usr/bin/perl
use strict;
use warnings;
use DBI; # Including the DBI module for databases

my %MYSQL = (
hostname => "localhost",
username => "root",
password => "password",
database => "customers"
);
my %ATTRIB = (
RaiseError => 1, # Enable error handling
AutoCommit => 0 # Enable transactions
);

# Establish a database connection
my $DB_CON = DBI->connect("dbi:mysql:$MYSQL{database}:$MYSQL{hostname}", "$MYSQL{username}", "$MYSQL{password}", \%ATTRIB)
|| die("Couldn't connect to the Database!
");

# Execute our sample transaction
eval {
# Update query
my $SQL_STR = "UPDATE cus_info SET cus_tp='$CUS_TP' WHERE cus_id=$CUS_ID";
my $SQL_EXEC = $DB_CON->prepare($SQL_STR);
$SQL_EXEC->execute();

# Insert query
$SQL_STR = "INSERT INTO product_main(prod_name,prod_stock) VALUES ('$PRODUCT_NAME','$PRODUCT_STOCK')";
$SQL_EXEC = $DB_CON->prepare($SQL_STR);
$SQL_EXEC->execute();

# Delete query
$SQL_STR = "DELETE FROM product_info WHERE prod_id='$PRODUCT_ID'";
$SQL_EXEC = $DB_CON->prepare($SQL_STR);
$SQL_EXEC->execute();

# Commit if all queries were successful
$DB_CON->commit();
};

# Rollback if any error occurred
if($@){
print "Transactions were rolled back
";
$DB_CON->rollback();
}
# Note: '$@' will be set if our eval did not compile. For more details, refer to the [Perl documentation](#).

# Close the database connection
$DB_CON->disconnect();
```

[Access the sample program and database dump on this GitHub gist](https://gist.github.com/krishanthisera/9bb72d95da08560290e4751633063f10).

## Conclusion

A database transaction is a sequence of jobs meant to run as a single unit. There are four key properties related to database transactions:

- Atomic
- Consistency
- Isolation
- Durability
2 changes: 1 addition & 1 deletion src/content/blog/edge-functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ __A Quick Note:__ For this setup, I'm leveraging a pipeline to deploy the infras

Why is this Dockerfile significant? Spacelift offers the capability to pair custom build environments with its runners. So, I've incorporated `Node.js` and `npm` into the runner's environment.

```Dockerfile
```dockerfile
# https://github.com/krishanthisera/aws-static-hosting/blob/main/Dockerfile
FROM public.ecr.aws/spacelift/runner-terraform:latest

Expand Down
Loading

0 comments on commit 9c3e35c

Please sign in to comment.