You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
MariaDB [(none)]> CREATE DATABASE minio_event_db CHARACTER SET utf8 COLLATE utf8_bin;
Query OK, 1 row affected (0.00 sec)
MariaDB [(none)]> CREATE USER 'minio'@'%' IDENTIFIED BY '@0bjectst0rage';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> GRANT ALL PRIVILEGES ON minio_event_db.* to minio@'%' identified by '0bjectst0rage';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> GRANT ALL PRIVILEGES ON minio_event_db.* to minio@localhost identified by '0bjectst0rage';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> GRANT ALL PRIVILEGES ON minio_event_db.* TO 'minio'@'%' WITH GRANT OPTION;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> GRANT ALL PRIVILEGES ON minio_event_db.* TO 'minio'@localhost WITH GRANT OPTION;
Query OK, 0 rows affected (0.00 sec)
Structure
type EventInfo struct {
EventType string
Key string
Records []minio.NotificationEvent
}
type ExifData struct {
EventInfo
ExifData map[string]*tiff.Tag
}
Webhook server code for lambda
package main
import (
"database/sql""encoding/json""fmt""io""log""net/http""net/url""os""strings""github.com/go-sql-driver/mysql"
router "github.com/gorilla/mux""github.com/minio/cli"
minio "github.com/minio/minio-go""github.com/rwcarlsen/goexif/exif""github.com/rwcarlsen/goexif/mknote""github.com/rwcarlsen/goexif/tiff"
)
const (
// Queries for format=namespace mode.upsertRowForNSMySQL=`INSERT INTO %s (key_name, value)VALUES (?, ?)ON DUPLICATE KEY UPDATE value=VALUES(value);`
)
varminioClient*minio.ClientvarupsertStatement*sql.Stmtfuncinit() {
// build from other parametersconfig:= mysql.Config{
User: "minio",
Passwd: "0bjectst0rage",
Net: "tcp",
Addr: "127.0.0.1:3306",
DBName: "minio_event_db",
}
db, err:=sql.Open("mysql", config.FormatDSN())
iferr!=nil {
log.Fatalln(err)
}
// ping to check that server is actually reachable.iferr=db.Ping(); err!=nil {
log.Fatalln(err)
}
// insert or update statementupsertStatement, err=db.Prepare(fmt.Sprintf(upsertRowForNSMySQL, "minio_ns_info"))
iferr!=nil {
log.Fatalln(err)
}
minioClient, err=minio.New("localhost:9000", "minio123", "minio12345", false)
iferr!=nil {
log.Fatalln(err)
}
}
typewalkerstruct {
metadatamap[string]*tiff.Tag
}
func (wwalker) Walk(name exif.FieldName, tag*tiff.Tag) error {
w.metadata["exif-"+strings.ToLower(string(name))] =tagreturnnil
}
funcgetExifData(r io.Reader) (map[string]*tiff.Tag, error) {
varmetadata=map[string]*tiff.Tag{}
// Optionally register camera makenote data parsing - currently Nikon and// Canon are supported.exif.RegisterParsers(mknote.All...)
x, err:=exif.Decode(r)
iferr!=nil {
returnnil, err
}
x.Walk(walker{metadata})
returnmetadata, nil
}
typeeventInfostruct {
EventTypestringKeystringRecords []minio.NotificationEvent
}
typeexifDatastruct {
eventInfoExifDatamap[string]*tiff.Tag
}
funcpostEventHandler(w http.ResponseWriter, r*http.Request) {
ifr.ContentLength==0 {
w.WriteHeader(http.StatusOK)
w.(http.Flusher).Flush()
return
}
ei:=eventInfo{}
jdecoder:=json.NewDecoder(r.Body)
iferr:=jdecoder.Decode(&ei); err!=nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
w.WriteHeader(http.StatusOK)
w.(http.Flusher).Flush()
ifstrings.HasPrefix(ei.EventType, "s3:ObjectCreated:") {
for_, record:=rangeei.Records {
objName, err:=url.PathUnescape(record.S3.Object.Key)
iferr!=nil {
log.Println(err)
return
}
obj, err:=minioClient.GetObject(record.S3.Bucket.Name, objName, minio.GetObjectOptions{})
iferr!=nil {
log.Println(err)
return
}
exifdata, err:=getExifData(obj)
iferr!=nil&&err!=io.EOF {
obj.Close()
log.Println(err)
return
}
obj.Close()
iferr==nil {
varb []byteb, err=json.Marshal(&exifData{
eventInfo: ei,
ExifData: exifdata,
})
iferr!=nil {
log.Println(err)
return
}
// upsert row into the tableif_, err=upsertStatement.Exec(ei.Key, b); err!=nil {
log.Println(err)
return
}
}
}
}
}
funcmain() {
app:=cli.NewApp()
app.Name="webhook"app.Usage="Simple Webhook Server"app.Flags= []cli.Flag{
cli.StringFlag{
Name: "address, a",
Value: ":8080",
Usage: "Address to listen on",
},
cli.BoolFlag{
Name: "log,l",
Usage: "Log to stderr",
},
cli.StringFlag{
Name: "cert,c",
Value: "",
Usage: "Certificate for TLS",
},
cli.StringFlag{
Name: "key,k",
Value: "",
Usage: "Key for TLS",
},
}
app.Action=func(c*cli.Context) {
address:=":8080"ifc.String("address") !="" {
address=c.String("address")
}
// Initialize router. `SkipClean(true)` stops gorilla/mux from// normalizing URL path.mux:=router.NewRouter().SkipClean(true)
// API RouterapiRouter:=mux.NewRoute().PathPrefix("/").Subrouter()
apiRouter.Methods("POST").HandlerFunc(postEventHandler)
cert:=c.String("cert")
key:=c.String("key")
// if cert or key are set, start TLSifcert!=""||key!="" {
// Both cert and key must be setifcert==""||key=="" {
log.Fatalln("Both a certificate and key must be provided for TLS")
}
log.Printf("Listening on https://%s\n", address)
log.Fatalln(http.ListenAndServeTLS(address, cert, key, mux))
} else {
log.Printf("Listening on http://%s\n", address)
log.Fatalln(http.ListenAndServe(address, mux))
}
}
app.Run(os.Args)
}