ProHoster > Blog > Amministrazione > Un esempiu di una applicazione guidata da l'avvenimentu basatu annantu à i webhooks in S3 object storage Mail.ru Cloud Solutions
Un esempiu di una applicazione guidata da l'avvenimentu basatu annantu à i webhooks in S3 object storage Mail.ru Cloud Solutions
L'architettura guidata da l'avvenimentu aumenta l'efficienza di u costu di i risorse utilizati perchè sò usati solu in u mumentu quandu sò necessarii. Ci hè parechje opzioni nantu à cumu implementà questu è micca creà entità cloud supplementari cum'è applicazioni di travagliu. È oghje ùn parleraghju micca di FaaS, ma di webhooks. Mostreraghju un esempiu tutoriale di gestione di l'avvenimenti utilizendu webhooks di almacenamentu di oggetti.
Uni pochi parolle nantu à u almacenamentu di l'ughjettu è i webhooks. L'almacenamiento d'ughjettu permette di almacenà qualsiasi dati in u nuvulu in forma di oggetti, accessibile via S3 o un altru API (secondu l'implementazione) via HTTP / HTTPS. Webhooks sò generalmente callbacks HTTP persunalizati. Sò tipicamenti attivati da un avvenimentu, cum'è u codice chì hè imbuttatu à un repository o un cumentu chì hè publicatu in un blog. Quandu si verifica un avvenimentu, u situ d'origine manda una dumanda HTTP à l'URL specificata per u webhook. In u risultatu, pudete fà avvenimenti in un situ attivate l'azzioni nantu à l'altru (lontana). In u casu induve u situ fonte hè un almacenamentu d'ughjettu, l'avvenimenti agisce cum'è cambiamenti à u so cuntenutu.
Esempii di casi simplici quandu una tale automatizazione pò esse usata:
Crea copie di tutti l'uggetti in un altru almacenamentu in nuvola. Copie deve esse creatu nantu à a mosca ogni volta chì i schedari sò aghjuntu o cambiatu.
Creazione automatica di una seria di miniature di fugliali grafici, aghjunghje filigrane à e fotografie, è altre mudificazioni di l'imaghjini.
Notificazione annantu à l'arrivu di novi documenti (per esempiu, un serviziu di cuntabilità distribuitu carica rapporti à u nuvulu, è u monitoraghju finanziariu riceve notificazioni nantu à novi rapporti, cuntrolla è analizà).
I casi un pocu più cumplessi implicanu, per esempiu, a generazione di una dumanda à Kubernetes, chì crea un pod cù i cuntenituri necessarii, passa i paràmetri di u compitu à ellu, è dopu a trasfurmazioni collapses the container.
Per esempiu, faremu una variante di u compitu 1, quandu i cambiamenti in u bucket d'almacenamiento d'oggetti di Mail.ru Cloud Solutions (MCS) sò sincronizati in l'almacenamiento d'oggetti AWS cù webhooks. In un veru casu caricatu, u travagliu asincronu deve esse furnitu registrendu webhooks in una fila, ma per u travagliu di furmazione faremu l'implementazione senza questu.
Schema di travagliu
U protocolu d'interazzione hè descrittu in dettagliu in Guida à i webhooks S3 nantu à MCS. U schema di travagliu cuntene i seguenti elementi:
serviziu di publicazione, chì si trova nantu à u latu di almacenamiento S3 è publica e dumande HTTP quandu u webnhook hè attivatu.
Servitore di ricezione Webhook, chì ascolta e dumande da u serviziu di publicazione HTTP è eseguisce l'azzioni appropritate. U servitore pò esse scrittu in ogni lingua; in u nostru esempiu, scriveremu u servitore in Go.
Una funziunalità particulari di l'implementazione di webhooks in l'API S3 hè a registrazione di u servitore di ricezione webhook in u serviziu di publicazione. In particulare, u servitore chì riceve u webhook deve cunfirmà l'abbonamentu à i missaghji da u serviziu di publicazione (in altre implementazioni di webhook, a cunferma di l'abbonamentu ùn hè generalmente micca necessariu).
Per quessa, u servitore di ricezione webhook deve sustene duie operazioni principali:
risponde à a dumanda di u serviziu di pubblicazione per cunfirmà a registrazione,
processà l'avvenimenti in entrata.
Installazione di un servitore di ricezione webhook
Per eseguisce u servitore di ricezione webhook, avete bisognu di un servitore Linux. In questu articulu, per esempiu, usemu una istanza virtuale chì implementemu in MCS.
Stallà u software necessariu è lanciamu u servitore di ricezione webhook.
ubuntu@ubuntu-basic-1-2-10gb:~$ sudo apt-get install git
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages were automatically installed and are no longer required:
bc dns-root-data dnsmasq-base ebtables landscape-common liblxc-common
liblxc1 libuv1 lxcfs lxd lxd-client python3-attr python3-automat
python3-click python3-constantly python3-hyperlink
python3-incremental python3-pam python3-pyasn1-modules
python3-service-identity python3-twisted python3-twisted-bin
python3-zope.interface uidmap xdelta3
Use 'sudo apt autoremove' to remove them.
Suggested packages:
git-daemon-run | git-daemon-sysvinit git-doc git-el git-email git-gui
gitk gitweb git-cvs git-mediawiki git-svn
The following NEW packages will be installed:
git
0 upgraded, 1 newly installed, 0 to remove and 46 not upgraded.
Need to get 3915 kB of archives.
After this operation, 32.3 MB of additional disk space will be used.
Get:1 http://MS1.clouds.archive.ubuntu.com/ubuntu bionic-updates/main
amd64 git amd64 1:2.17.1-1ubuntu0.7 [3915 kB]
Fetched 3915 kB in 1s (5639 kB/s)
Selecting previously unselected package git.
(Reading database ... 53932 files and directories currently installed.)
Preparing to unpack .../git_1%3a2.17.1-1ubuntu0.7_amd64.deb ...
Unpacking git (1:2.17.1-1ubuntu0.7) ...
Setting up git (1:2.17.1-1ubuntu0.7) ...
Clone u cartulare cù u servitore di ricezione webhook:
Andate à u bucket per quale cunfiguremu webhooks è cliccate nantu à l'ingranaggio:
Andate à a tabulazione Webhooks è cliccate Aggiungi:
Riempite i campi:
ID - u nome di u webhook.
Avvenimentu - quale avvenimenti trasmette. Avemu stabilitu a trasmissione di tutti l'avvenimenti chì si verificanu quandu u travagliu cù i schedari (aghjunghje è sguassà).
URL - webhook chì riceve l'indirizzu di u servitore.
Prefissu / suffissu di filtru hè un filtru chì vi permette di generà webhooks solu per l'uggetti chì i nomi currispondenu à certe regule. Per esempiu, per u webhook per attivà solu i schedari cù l'estensione .png, in Filtru suffissu avete bisognu di scrive "png".
Attualmente, solu i porti 80 è 443 sò supportati per accede à u servitore di ricezione webhook.
Facemu cliccà Aghjunghjite un ganciu è videremu i seguenti:
Hook aghjustatu.
U servitore di ricezione di u webhook mostra in i so logs u prugressu di u prucessu di registrazione di u ganciu:
A registrazione hè cumpleta. In a sezione dopu, avemu da piglià un ochju più vicinu à l'algoritmu di u funziunamentu di u servitore di ricezione webhook.
Descrizzione di u servitore di ricezione webhook
In u nostru esempiu, u servitore hè scrittu in Go. Fighjemu i principii basi di u so funziunamentu.
cunfirma a registrazione nantu à u serviziu di pubblicazione (andà à a funzione SubscriptionConfirmation),
processa i webhooks in entrata (funzione Gorecords).
E funzioni HmacSha256 è HmacSha256hex sò implementazioni di l'algoritmi di crittografia HMAC-SHA256 è HMAC-SHA256 cù output cum'è una stringa di numeri esadecimali per calculà a firma.
main hè a funzione principale, processa i paràmetri di a linea di cumanda è registra i gestori di URL.
Paràmetri di linea di cumanda accettati da u servitore:
-port hè u portu nantu à quale u servitore stà à sente.
-address - indirizzu IP chì u servitore ascolterà.
-script hè un prugramma esternu chì hè chjamatu per ogni hook entrante.
Fighjemu un ochju più vicinu à alcune di e funzioni:
//Webhook
func Webhook(w http.ResponseWriter, req *http.Request) {
// Read body
body, err := ioutil.ReadAll(req.Body)
defer req.Body.Close()
if err != nil {
http.Error(w, err.Error(), 500)
return
}
// log request
log.Printf("[%s] incoming HTTP request from %sn", req.Method, req.RemoteAddr)
// check if we got subscription confirmation request
if strings.Contains(string(body),
""Type":"SubscriptionConfirmation"") {
SubscriptionConfirmation(w, req, body)
} else {
GotRecords(w, req, body)
}
}
Questa funzione determina se una dumanda per cunfirmà a registrazione o un webhook hè ghjuntu. Comu seguita da ducumentazione, Se a registrazione hè cunfirmata, a seguente struttura Json hè ricevutu in a dumanda Post:
POST http://test.com HTTP/1.1
x-amz-sns-messages-type: SubscriptionConfirmation
content-type: application/json
{
"Timestamp":"2019-12-26T19:29:12+03:00",
"Type":"SubscriptionConfirmation",
"Message":"You have chosen to subscribe to the topic $topic. To confirm the subscription you need to response with calculated signature",
"TopicArn":"mcs2883541269|bucketA|s3:ObjectCreated:Put",
"SignatureVersion":1,
"Token":«RPE5UuG94rGgBH6kHXN9FUPugFxj1hs2aUQc99btJp3E49tA»
}
In cunsiquenza, secondu a dumanda, avete bisognu di capiscenu cumu processà i dati. Aghju sceltu l'entrata cum'è indicatore "Type":"SubscriptionConfirmation", postu chì hè presente in a dumanda di cunferma di abbunamentu è ùn hè micca presente in u webhook. Basatu nantu à a presenza / assenza di sta entrata in a dumanda POST, l'esekzione ulteriore di u prugramma passa sia à a funzione SubscriptionConfirmation, o in a funzione GotRecords.
Ùn cunsideremu micca a funzione SubscriptionConfirmation in dettagliu; hè implementata secondu i principii stabiliti in ducumentazione. Pudete vede u codice fonte per sta funzione à repository git di prughjettu.
A funzione GotRecords analizza una dumanda in entrata è per ogni ughjettu Record chjama un script esternu (chì u nome hè statu passatu in u paràmetru -script) cù i paràmetri:
nome di bucket
chjave di l'ughjettu
azzione:
copia - se in a dumanda originale EventName = ObjectCreated | PutObject | PutObjectCopy
sguassà - se in a dumanda originale EventName = ObjectRemoved | Elimina l'Oggettu
Cusì, se un ganciu arriva cù una dumanda Post, cum'è descritta Lingua, è u paràmetru -script=script.sh allora u script serà chjamatu cusì:
script.sh bucketA some-file-to-bucket copy
Hè da esse capitu chì stu servitore di ricezione webhook ùn hè micca una suluzione cumpleta di produzzione, ma un esempiu simplificatu di una implementazione pussibule.
Esempiu di travagliu
Sincronizemu i fugliali da u bucket principale in MCS à u bucket di salvezza in AWS. U bucket principale hè chjamatu myfiles-ash, a copia di salvezza hè chjamata myfiles-backup (a cunfigurazione di bucket in AWS hè fora di u scopu di questu articulu). In cunsiquenza, quandu un schedariu hè piazzatu in u bucket principale, a so copia deve cumparisce in a copia di salvezza, è quandu hè sguassata da u principale, deve esse sguassata in quella di salvezza.
Travaglieremu cù buckets usendu l'utilità awscli, chì hè cumpatibile cù u almacenamentu in nuvola MCS è u almacenamentu in nuvola AWS.
ubuntu@ubuntu-basic-1-2-10gb:~$ sudo apt-get install awscli
Reading package lists... Done
Building dependency tree
Reading state information... Done
After this operation, 34.4 MB of additional disk space will be used.
Unpacking awscli (1.14.44-1ubuntu1) ...
Setting up awscli (1.14.44-1ubuntu1) ...
Configuremu l'accessu à l'API S3 MCS:
ubuntu@ubuntu-basic-1-2-10gb:~$ aws configure --profile mcs
AWS Access Key ID [None]: hdywEPtuuJTExxxxxxxxxxxxxx
AWS Secret Access Key [None]: hDz3SgxKwXoxxxxxxxxxxxxxxxxxx
Default region name [None]:
Default output format [None]:
Configuremu l'accessu à l'API AWS S3:
ubuntu@ubuntu-basic-1-2-10gb:~$ aws configure --profile aws
AWS Access Key ID [None]: AKIAJXXXXXXXXXXXX
AWS Secret Access Key [None]: dfuerphOLQwu0CreP5Z8l5fuXXXXXXXXXXXXXXXX
Default region name [None]:
Default output format [None]:
Cuntrollamu l'accessi:
À AWS:
ubuntu@ubuntu-basic-1-2-10gb:~$ aws s3 ls --profile aws
2020-07-06 08:44:11 myfiles-backup
Per MCS, quandu eseguite u cumandimu avete bisognu di aghjunghje -endpoint-url:
Videmu cumu si travaglia. À traversu Interfaccia web MCS aghjunghje u schedariu test.txt à u bucket myfiles-ash. I logs di a cunsola mostranu chì una dumanda hè stata fatta à u servitore webhook:
2020/07/06 09:43:08 [POST] incoming HTTP request from
95.163.216.92:56612
download: s3://myfiles-ash/test.txt to ../../../tmp/myfiles-ash/test.txt
upload: ../../../tmp/myfiles-ash/test.txt to
s3://myfiles-backup/test.txt
Cuntrollamu u cuntenutu di u bucket myfiles-backup in AWS:
Avà, attraversu l 'interfaccia web, avemu da sguassà u schedariu da u bucket myfiles-ash.
Logs di u servitore:
2020/07/06 09:44:46 [POST] incoming HTTP request from
95.163.216.92:58224
delete: s3://myfiles-backup/test.txt
Cuntenutu di u bucket:
ubuntu@ubuntu-basic-1-2-10gb:~/s3-webhook$ aws s3 --profile aws ls
myfiles-backup
ubuntu@ubuntu-basic-1-2-10gb:~$
U schedariu hè sguassatu, u prublema hè risolta.
Conclusioni è ToDo
Tuttu u codice utilizatu in questu articulu hè in u mo repository. Ci sò ancu esempi di scripts è esempi di cuntà signatures per registrà webhooks.
Stu codice hè nunda di più chè un esempiu di cumu si pò aduprà S3 webhooks in u vostru attività. Cumu l'aghju dettu à u principiu, se pensa à aduprà un tali servitore in a produzzione, avete bisognu di almenu riscrive u servitore per u travagliu asincronu: registrà i webhooks entranti in una fila (RabbitMQ o NATS), è da quì analizà è processanu. cù l'applicazioni di u travagliu. Altrimenti, quandu i webhooks arrivanu massivamente, pudete scontru una mancanza di risorse di u servitore per cumpiendu i travaglii. A prisenza di fila permette di distribuisce u servitore è i travagliadori, è ancu di risolve i prublemi cù a ripetizione di i travaglii in casu di fallimenti. Hè ancu cunsigliatu di cambià u logging à un più detallatu è standardizatu.