diff --git a/GoGetScript.sh b/GoGetScript.sh new file mode 100755 index 0000000000000000000000000000000000000000..950d3f0da2ab50ca816a1ed2fcf38758110b42c5 --- /dev/null +++ b/GoGetScript.sh @@ -0,0 +1,112 @@ +echo "Installing : \"github.com/allegro/bigcache\"" +go get "github.com/allegro/bigcache" +echo "Done" +NOW=$(date +"%d-%b-%Y %H:%M:%S") +echo $NOW " : Installed \"github.com/allegro/bigcache\"" >> InstallLogs.txt + + +echo "Installing : \"github.com/spf13/viper\"" +go get "github.com/spf13/viper" +echo "Done" +NOW=$(date +"%d-%b-%Y %H:%M:%S") +echo $NOW " : Installed \"github.com/spf13/viper\"" >> InstallLogs.txt + + +echo "Installing : \"github.com/gocraft/dbr\"" +go get "github.com/gocraft/dbr" +echo "Done" +NOW=$(date +"%d-%b-%Y %H:%M:%S") +echo $NOW " : Installed \"github.com/gocraft/dbr\"" >> InstallLogs.txt + + +echo "Installing : \"gopkg.in/mgo.v2\"" +go get "gopkg.in/mgo.v2" +echo "Done" +NOW=$(date +"%d-%b-%Y %H:%M:%S") +echo $NOW " : Installed \"gopkg.in/mgo.v2\"" >> InstallLogs.txt + + +echo "Installing : \"github.com/garyburd/redigo/redis\"" +go get "github.com/garyburd/redigo/redis" +echo "Done" +NOW=$(date +"%d-%b-%Y %H:%M:%S") +echo $NOW " : Installed \"github.com/garyburd/redigo/redis\"" >> InstallLogs.txt + + +echo "Installing : \"github.com/stretchr/testify/assert\"" +go get "github.com/stretchr/testify/assert" +echo "Done" +NOW=$(date +"%d-%b-%Y %H:%M:%S") +echo $NOW " : Installed \"github.com/stretchr/testify/assert\"" >> InstallLogs.txt + + +echo "Installing : \"github.com/labstack/echo\"" +go get "github.com/labstack/echo" +echo "Done" +NOW=$(date +"%d-%b-%Y %H:%M:%S") +echo $NOW " : Installed \"github.com/labstack/echo\"" >> InstallLogs.txt + + +echo "Installing : \"gopkg.in/mgo.v2/bson\"" +go get "gopkg.in/mgo.v2/bson" +echo "Done" +NOW=$(date +"%d-%b-%Y %H:%M:%S") +echo $NOW " : Installed \"gopkg.in/mgo.v2/bson\"" >> InstallLogs.txt + + +echo "Installing : \"github.com/dgrijalva/jwt-go\"" +go get "github.com/dgrijalva/jwt-go" +echo "Done" +NOW=$(date +"%d-%b-%Y %H:%M:%S") +echo $NOW " : Installed \"github.com/dgrijalva/jwt-go\"" >> InstallLogs.txt + + +echo "Installing : \"github.com/labstack/echo/middleware\"" +go get "github.com/labstack/echo/middleware" +echo "Done" +NOW=$(date +"%d-%b-%Y %H:%M:%S") +echo $NOW " : Installed \"github.com/labstack/echo/middleware\"" >> InstallLogs.txt + + +echo "Installing : \"github.com/sirupsen/logrus\"" +go get "github.com/sirupsen/logrus" +echo "Done" +NOW=$(date +"%d-%b-%Y %H:%M:%S") +echo $NOW " : Installed \"github.com/sirupsen/logrus\"" >> InstallLogs.txt + + +echo "Installing : \"github.com/go-playground/locales/en\"" +go get "github.com/go-playground/locales/en" +echo "Done" +NOW=$(date +"%d-%b-%Y %H:%M:%S") +echo $NOW " : Installed \"github.com/go-playground/locales/en\"" >> InstallLogs.txt + + +echo "Installing : \"gopkg.in/go-playground/validator.v9\"" +go get "gopkg.in/go-playground/validator.v9" +echo "Done" +NOW=$(date +"%d-%b-%Y %H:%M:%S") +echo $NOW " : Installed \"gopkg.in/go-playground/validator.v9\"" >> InstallLogs.txt + + +echo "Installing : \"github.com/go-playground/universal-translator\"" +go get "github.com/go-playground/universal-translator" +echo "Done" +NOW=$(date +"%d-%b-%Y %H:%M:%S") +echo $NOW " : Installed \"github.com/go-playground/universal-translator\"" >> InstallLogs.txt + + +echo "Installing : \"gopkg.in/go-playground/validator.v9/translations/en\"" +go get "gopkg.in/go-playground/validator.v9/translations/en" +echo "Done" +NOW=$(date +"%d-%b-%Y %H:%M:%S") +echo $NOW " : Installed \"gopkg.in/go-playground/validator.v9/translations/en\"" >> InstallLogs.txt + +echo "******************************************" +echo "Installation complete" +echo "******************************************" + +NOW=$(date +"%d-%b-%Y %H:%M:%S") +echo "******************************************" >> InstallLogs.txt +echo $NOW "Installation complete" >> InstallLogs.txt +echo "******************************************" >> InstallLogs.txt \ No newline at end of file diff --git a/InstallLogs.txt b/InstallLogs.txt new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/coreos/DALMySQL.go b/coreos/DALMySQL.go new file mode 100644 index 0000000000000000000000000000000000000000..c725f5d4ecc191274fef39e0fa88a6b798077462 --- /dev/null +++ b/coreos/DALMySQL.go @@ -0,0 +1,26 @@ +package coreos + +import ( + "sync" + + "GolangFullStack/server/api/server/config" + + "github.com/gocraft/dbr" +) + +// Hold a single global connection (pooling provided by sql driver) +var sqlConnection *dbr.Connection +var sqlOnce sync.Once + +//GetSQLConnection to db +func GetSQLConnection() (*dbr.Connection, error) { + sqlOnce.Do(func() { + // create a connection db(e.g. "postgres", "mysql", or "sqlite3") + connection, _ := dbr.Open("mysql", config.MysqlDSN, nil) + + // connection.SetMaxIdleConns(10) + // connection.SetMaxOpenConns(5) + sqlConnection = connection + }) + return sqlConnection, nil +} diff --git a/coreos/DALNoSQL.go b/coreos/DALNoSQL.go new file mode 100644 index 0000000000000000000000000000000000000000..a6e374accfb13000b5913f3f6870a761affa0d7c --- /dev/null +++ b/coreos/DALNoSQL.go @@ -0,0 +1,43 @@ +package coreos + +import ( + "GolangFullStack/server/api/server/config" + "fmt" + "sync" + + mgo "gopkg.in/mgo.v2" +) + +var instance *mgo.Session +var once sync.Once + +//GetMongoConnection method +func GetMongoConnection() *mgo.Session { + once.Do(func() { + Host := []string{ + config.MONGODSN, + } + const ( + Username = "" + Password = "" + Database = config.DBNAME + ) + + session, err := mgo.DialWithInfo(&mgo.DialInfo{ + Addrs: Host, + Username: Username, + Password: Password, + Database: Database, + }) + if err != nil { + + } + //defer session.Close() + + fmt.Printf("Connected to replica set %v!\n", session.LiveServers()) + + instance = session + + }) + return instance +} diff --git a/coreos/DALRedis.go b/coreos/DALRedis.go new file mode 100644 index 0000000000000000000000000000000000000000..f4b876e38be3f13855a089c38302d23c49876506 --- /dev/null +++ b/coreos/DALRedis.go @@ -0,0 +1,20 @@ +package coreos + +import ( + "GolangFullStack/server/api/server/config" + + "github.com/garyburd/redigo/redis" +) + +//GetWorkPool ss +func GetWorkPool() *redis.Pool { + var redisPool = &redis.Pool{ + MaxActive: 5, + MaxIdle: 5, + Wait: true, + Dial: func() (redis.Conn, error) { + return redis.Dial("tcp", config.REDISDSN, redis.DialDatabase(3)) + }, + } + return redisPool +} diff --git a/coreos/EchoHelper.go b/coreos/EchoHelper.go new file mode 100644 index 0000000000000000000000000000000000000000..fd8fbe73cf92c4611607352ab3a63d383721c856 --- /dev/null +++ b/coreos/EchoHelper.go @@ -0,0 +1,21 @@ +package coreos + +import ( + "sync" + + "github.com/labstack/echo" +) + +var echoInstance *echo.Echo +var echoOnce sync.Once + +//GetEcho method +func GetEcho() *echo.Echo { + echoOnce.Do(func() { + e := echo.New() + + echoInstance = e + + }) + return echoInstance +} diff --git a/coreos/cacheHelper.go b/coreos/cacheHelper.go new file mode 100644 index 0000000000000000000000000000000000000000..7a71625a1a33116511af67524a559e87f4e50b2a --- /dev/null +++ b/coreos/cacheHelper.go @@ -0,0 +1,55 @@ +package coreos + +import ( + "GolangFullStack/server/api/server/config" + "fmt" + "time" + + "github.com/allegro/bigcache" +) + +var bigcacheConfig = bigcache.Config{ + // number of shards (must be a power of 2) + // Shards: 4096, + Shards: config.BIGCACHEShards, + // time after which entry can be evicted + LifeWindow: config.BIGCACHELifeWindow * time.Hour, + // rps * lifeWindow, used only in initial memory allocation + MaxEntriesInWindow: 1000 * 10 * 60, + // MaxEntriesInWindow: 10, + // max entry size in bytes, used only in initial memory allocation + MaxEntrySize: config.BIGCACHEMaxEntrySize, + // prints information about additional memory allocation + Verbose: config.BIGCACHEVerbose, + // cache will not allocate more memory than this limit, value in MB + // if value is reached then the oldest entries can be overridden for the new ones + // 0 value means no size limit + HardMaxCacheSize: config.BIGCACHEHardMaxCacheSize, + // callback fired when the oldest entry is removed because of its + // expiration time or no space left for the new entry. Default value is nil which + // means no callback and it prevents from unwrapping the oldest entry. + OnRemove: nil, +} + +var cache, initErr = bigcache.NewBigCache(bigcacheConfig) + +//GetValue GetValue +func GetValue(key string) ([]byte, error) { + return cache.Get(key) +} + +//SetValue SetValue +func SetValue(key string, value []byte) { + cache.Set(key, value) +} + +//GetLength GetLength +func GetLength() int { + return cache.Len() +} + +//Callback function executed when cache element is removed. +//Executed only when onRemove of cache config poting to this function +func onRemove(key string, entry []byte) { + fmt.Println(key + " removed at " + time.Now().String()) +} diff --git a/coreos/configHelper.go b/coreos/configHelper.go new file mode 100644 index 0000000000000000000000000000000000000000..e9a2ed71d8fc3723479ca7dbf680fe85051dbf5b --- /dev/null +++ b/coreos/configHelper.go @@ -0,0 +1,27 @@ +package coreos + +import ( + "fmt" + + "github.com/spf13/viper" +) + +//InitViper function to initialize viper +func InitViper() { + viper.SetConfigName("config") // name of config file (without extension) + viper.AddConfigPath(".") // optionally look for config in the working directory + err := viper.ReadInConfig() + // Find and read the config file + if err != nil { // Handle errors reading the config file + panic(fmt.Errorf("Fatal error config file %s ", err)) + } +} + +//GetConfig method to get configs from config file +func GetConfig(keyName string) string { + + keyValue := viper.GetString(keyName) + + return keyValue + +} diff --git a/coreos/dbconfig.go b/coreos/dbconfig.go new file mode 100644 index 0000000000000000000000000000000000000000..7279af75cab543fc94e3073b7184016804901b97 --- /dev/null +++ b/coreos/dbconfig.go @@ -0,0 +1,29 @@ +package coreos + +import ( + "os" + + "gopkg.in/mgo.v2" +) + +type DB struct { + Session *mgo.Session +} + +func (db *DB) DoDial() (s *mgo.Session, err error) { + return mgo.Dial(DBUrl()) +} + +func (db *DB) Name() string { + return "swapnilapp" +} + +func DBUrl() string { + dburl := os.Getenv("MONGOHQ_URL") + + if dburl == "" { + dburl = "localhost" + } + + return dburl +} diff --git a/coreos/dbconfig_test.go b/coreos/dbconfig_test.go new file mode 100644 index 0000000000000000000000000000000000000000..b5f02de1899b30a0ff4f5e911eda076a91f4825e --- /dev/null +++ b/coreos/dbconfig_test.go @@ -0,0 +1,35 @@ +package coreos + +import ( + "os" + "testing" + + "github.com/stretchr/testify/assert" +) + +var db DB = DB{} + +func cleanEnv() { + os.Setenv("MONGOHQ_URL", "") +} + +func TestGetDbUrl(t *testing.T) { + + assert.Equal(t, "localhost", DBUrl()) + + os.Setenv("MONGOHQ_URL", "abc") + + assert.Equal(t, "abc", DBUrl()) + + cleanEnv() +} + +func TestDBName(t *testing.T) { + assert.Equal(t, "swapnilapp", db.Name()) +} + +func BenchmarkDoDial(b *testing.B) { + for i := 0; i < b.N; i++ { + db.DoDial() + } +} diff --git a/coreos/fileHelper.go b/coreos/fileHelper.go new file mode 100644 index 0000000000000000000000000000000000000000..b443d6a992225e4f131785c8ee12e938678dd700 --- /dev/null +++ b/coreos/fileHelper.go @@ -0,0 +1,281 @@ +package coreos + +import ( + "archive/zip" + "io" + "io/ioutil" + "os" + "path/filepath" + "strings" +) + +var searchResult []string +var searchFileName string + +// ReadFile reads contents from provided file path +func ReadFile(filePath string) ([]byte, error) { + return ioutil.ReadFile(filePath) + +} + +//CreateFile creates a new file +func CreateFile(filePath string) (*os.File, error) { + return os.Create(filePath) +} + +// WriteFile writes provided bytes to file +func WriteFile(filePath string, data []byte) error { + return ioutil.WriteFile(filePath, data, 0644) +} + +//AppendFile appends prvided data/text to file +func AppendFile(filename string, text string) (int, error) { + + f, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY, 0600) + if err != nil { + return 0, err + } + + defer f.Close() + + return f.WriteString(text) +} + +//DeleteFile deletes provided file path +func DeleteFile(filePath string) error { + return os.Remove(filePath) +} + +// RenameFile renames/moves file from old path to new path +func RenameFile(oldFilePath, newFilePath string) error { + return os.Rename(oldFilePath, newFilePath) +} + +// CreateDirectory creates directory using provided path +func CreateDirectory(directoryPath string) error { + return os.Mkdir(directoryPath, 0777) +} + +// DeleteDirectory creates directory using provided path +func DeleteDirectory(directoryPath string) error { + return os.RemoveAll(directoryPath) +} + +//ListDirectory returns list of all available components of directory +func ListDirectory(directoryPath string) ([]os.FileInfo, error) { + return ioutil.ReadDir(directoryPath) +} + +//Zip Zip +func Zip(source, target string) error { + zipfile, err := os.Create(target) + if err != nil { + return err + } + defer zipfile.Close() + + archive := zip.NewWriter(zipfile) + defer archive.Close() + + info, err := os.Stat(source) + if err != nil { + return nil + } + + var baseDir string + if info.IsDir() { + baseDir = filepath.Base(source) + } + + filepath.Walk(source, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + + header, err := zip.FileInfoHeader(info) + if err != nil { + return err + } + + if baseDir != "" { + header.Name = filepath.Join(baseDir, strings.TrimPrefix(path, source)) + } + + if info.IsDir() { + header.Name += "/" + } else { + header.Method = zip.Deflate + } + + writer, err := archive.CreateHeader(header) + if err != nil { + return err + } + + if info.IsDir() { + return nil + } + + file, err := os.Open(path) + if err != nil { + return err + } + defer file.Close() + _, err = io.Copy(writer, file) + return err + }) + + return err +} + +//Unzip Unzip +func Unzip(archive, target string) error { + reader, err := zip.OpenReader(archive) + if err != nil { + return err + } + + if err := os.MkdirAll(target, 0755); err != nil { + return err + } + + for _, file := range reader.File { + path := filepath.Join(target, file.Name) + if file.FileInfo().IsDir() { + os.MkdirAll(path, file.Mode()) + continue + } + + fileReader, err := file.Open() + if err != nil { + return err + } + defer fileReader.Close() + + targetFile, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, file.Mode()) + if err != nil { + return err + } + defer targetFile.Close() + + if _, err := io.Copy(targetFile, fileReader); err != nil { + return err + } + } + + return nil +} + +//MoveDirectory MoveDirectory +func MoveDirectory(source, destination string) error { + return os.Rename(source, destination) +} + +//MoveFile MoveFile +func MoveFile(source, destination string) error { + return os.Rename(source, destination) +} + +//CopyFile CopyFile +func CopyFile(source, destination string) error { + // return os.Rename(source, destination) + + data, err := ioutil.ReadFile(source) + if err != nil { + return err + } + err = ioutil.WriteFile(destination, data, 0644) + + return err +} + +//ReplaceFile ReplaceFile +func ReplaceFile(data []byte, destination string) error { + + err := ioutil.WriteFile(destination, data, 0644) + + return err +} + +//TruncateFile TruncateFile +func TruncateFile(path string, size int64) error { + return os.Truncate(path, size) +} + +//SeekFile SeekFile +// func SeekFile(path string, offset int64) error { +// file, err := os.OpenFile(path, os.O_RDWR, 0600) +// if err != nil { +// return err +// } + +// defer file.Close() + +// _, err = file.Seek(offset, 0) + +// return err +// } + +//FileInfo FileInfo +func FileInfo(path string) (os.FileInfo, error) { + return os.Stat(path) +} + +//FileSearch FileSearch +func FileSearch(fileName, path string) ([]string, error) { + searchFileName = fileName + searchDirectory, err := os.Open(path) + if err != nil { + return searchResult, err + } + defer searchDirectory.Close() + + testFileInfo, _ := searchDirectory.Stat() + if !testFileInfo.IsDir() { + return searchResult, err + } + + err = filepath.Walk(path, findFile) + if err != nil { + return searchResult, err + } + + return searchResult, nil + +} + +func findFile(path string, fileInfo os.FileInfo, err error) error { + + if err != nil { + + return err + } + + // get absolute path of the folder that we are searching + absolute, err := filepath.Abs(path) + if err != nil { + + return err + } + + if fileInfo.IsDir() { + testDir, err := os.Open(absolute) + if err != nil { + return err + } + testDir.Close() + return nil + } + + matched, err := filepath.Match(searchFileName, fileInfo.Name()) + if err != nil { + return err + } + + if matched { + add := absolute + searchResult = append(searchResult, add) + } + + return nil +} diff --git a/coreos/hDataConvertor.go b/coreos/hDataConvertor.go new file mode 100644 index 0000000000000000000000000000000000000000..77e9dd1d01eacf02349208591eda33c2400ce06d --- /dev/null +++ b/coreos/hDataConvertor.go @@ -0,0 +1,25 @@ +package coreos + +import ( + "encoding/json" + "log" + + "gopkg.in/mgo.v2/bson" +) + +//ConvertToJSON converts []bson to json +// func ConvertToJSON(data []bson.M) string { +// respBody, err := json.MarshalIndent(data, "", "") +// if err != nil { +// log.Fatal(err) +// } +// return string(respBody) +// } +//ConvertToJSON converts []bson to json +func ConvertToJSON(data []bson.M) string { + respBody, err := json.MarshalIndent(data, "", "") + if err != nil { + log.Fatal(err) + } + return string(respBody) +} diff --git a/coreos/jwtHelper.go b/coreos/jwtHelper.go new file mode 100644 index 0000000000000000000000000000000000000000..69c976c91aeac1c4f388e9b57db6553a9e87a22b --- /dev/null +++ b/coreos/jwtHelper.go @@ -0,0 +1,48 @@ +package coreos + +import ( + "fmt" + + "strings" + + jwt "github.com/dgrijalva/jwt-go" + "github.com/labstack/echo/middleware" +) + +const ( + //JwtKey for key of EP + JwtKey = "MKCL-EP-1234567890" +) + +// JwtCustomClaims are custom claims extending default ones. +type JwtCustomClaims struct { + Username string `json:"username"` + jwt.StandardClaims +} + +// GetJwtConfig middleware with the custom claims type +func GetJwtConfig() middleware.JWTConfig { + jwtConfig := middleware.JWTConfig{ + Claims: &JwtCustomClaims{}, + SigningKey: []byte(JwtKey), + } + return jwtConfig +} + +// DecodeToken decode token +func DecodeToken(tokenFromRequest string) jwt.MapClaims { + tokenFromRequest = strings.Trim(strings.Split(tokenFromRequest, "Bearer")[1], " ") + // get data i.e.Claims from token + token, _ := jwt.Parse(tokenFromRequest, func(token *jwt.Token) (interface{}, error) { + // Don't forget to validate the alg is what you expect: + if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok { + return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"]) + } + return JwtKey, nil + }) + claims, ok := token.Claims.(jwt.MapClaims) + if !ok { + return nil + } + return claims +} diff --git a/coreos/loggingHelper.go b/coreos/loggingHelper.go new file mode 100644 index 0000000000000000000000000000000000000000..594de71d630b2e886008af5137f52525223f458d --- /dev/null +++ b/coreos/loggingHelper.go @@ -0,0 +1,48 @@ +package coreos + +import ( + "os" + + "github.com/sirupsen/logrus" +) + +var logger = logrus.New() + +func init() { + //log.Formatter = new(logger.JSONFormatter) + logger.Formatter = new(logrus.TextFormatter) // default + logger.Level = logrus.ErrorLevel + + file, err := os.OpenFile("GolangFullStack.log", os.O_CREATE|os.O_APPEND, 0666) + if err == nil { + logger.Out = file + } else { + logger.Info("Failed to log to file, using default stderr") + } + +} + +//Debug Debug +func Debug(message string) { + logger.Debug(message) +} + +//Info Info +func Info(message string) { + logger.Info(message) +} + +//Warn Warn +func Warn(message string) { + logger.Warn(message) +} + +//Error Error +func Error(message string) { + logger.Error(message) +} + +//Panic Panic +func Panic(message string) { + logger.Panic(message) +} diff --git a/coreos/smsHelper.go b/coreos/smsHelper.go new file mode 100644 index 0000000000000000000000000000000000000000..e8517554634091414c18a5047623ed300d676320 --- /dev/null +++ b/coreos/smsHelper.go @@ -0,0 +1,45 @@ +package coreos + +import ( + "GolangFullStack/server/api/server/config" + "fmt" + "io/ioutil" + "log" + "net/http" + "net/url" +) + +type SMS struct { + MobileNumber string + Message string + UserName string + Password string + SenderID string + CDMAHeader string +} + +// SendSMS : send SMS Service +func SendSMS(smsObject SMS) error { + var postURL string + postURL = config.SMSAPIURL + "?UserName=" + smsObject.UserName + "&password=" + smsObject.Password + "&MobileNo=" + smsObject.MobileNumber + "&SenderID=" + smsObject.SenderID + "&CDMAHeader=" + smsObject.CDMAHeader + "&Message=" + url.QueryEscape(smsObject.Message) + // fmt.Println(postURL) + resp, err := http.Get(postURL) + if err != nil { + // handle error + log.Fatal(err) + } + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + fmt.Println(body) + return err +} + +// GetSMSObject : get sms object +func GetSMSObject() SMS { + var smsObject = new(SMS) + smsObject.SenderID = "MKCLTD" + smsObject.UserName = "solar1_trans" + smsObject.Password = "trans123" + smsObject.CDMAHeader = "MKCLTD" + return *smsObject +} diff --git a/coreos/validationHelper.go b/coreos/validationHelper.go new file mode 100644 index 0000000000000000000000000000000000000000..449466cab5bab1059bece630653ea801257352b5 --- /dev/null +++ b/coreos/validationHelper.go @@ -0,0 +1,55 @@ +package coreos + +import ( + "github.com/go-playground/locales/en" + "gopkg.in/go-playground/validator.v9" + + ut "github.com/go-playground/universal-translator" + en_translations "gopkg.in/go-playground/validator.v9/translations/en" +) + +//Validate method +func Validate(s interface{}) map[string]string { + var validate *validator.Validate + var uni *ut.UniversalTranslator + + validate = validator.New() + + en := en.New() + //mr := mr.New() + + uni = ut.New(en, en) + + trans, _ := uni.GetTranslator("en") + en_translations.RegisterDefaultTranslations(validate, trans) + // mr_translations.RegisterDefaultTranslations(validate, trans) + + //For custom error message + // validate.RegisterTranslation("required", trans, func(ut ut.Translator) error { + // // fmt.Println(ut) + // return ut.Add("required", "{0} must have a value!", true) // see universal-translator for details + + // }, func(ut ut.Translator, fe validator.FieldError) string { + // t, _ := ut.T("required", fe.Field()) + + // return t + // }) + + err := validate.Struct(s) + + if err != nil { + errs := err.(validator.ValidationErrors) + + //customErrs := map[string]string{} + customErrs := make(map[string]string, len(errs)) + + for _, e := range errs { + // can translate each error one at a time. + customErrs[e.Namespace()] = e.Translate(trans) + + } + + return customErrs + } + return nil +}