fdb.go 10.7 KiB
Newer Older
Ajit Jagtap's avatar
Ajit Jagtap committed
//@author  Ajit Jagtap
//@version Thu Jul 05 2018 06:14:04 GMT+0530 (IST)

// Package fdb will help you access data from FDB
package fdb

import (
Roshan Patil's avatar
Roshan Patil committed
	"path/filepath"
Ajit Jagtap's avatar
Ajit Jagtap committed
	"sync"
	"corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/statemdl"

	"github.com/pquerna/ffjson/ffjson"

Roshan Patil's avatar
Roshan Patil committed
	"corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/hashmdl"

	"corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/securitymdl"
Ajit Jagtap's avatar
Ajit Jagtap committed

Ajit Jagtap's avatar
Ajit Jagtap committed
	"corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/cachemdl"
	"corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/constantmdl"
	"corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/errormdl"
	"corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/filemdl"
	"corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/loggermdl"
Ajit Jagtap's avatar
Ajit Jagtap committed

	"github.com/tidwall/gjson"
)

// securityRequired for securing fdb data
var securityRequired = false

// downloadFromInternet flag enables filedownload from internet
// var downloadFromInternet = false
// var hostAddressForDataFiles = ""
// var splitString = ""

var defaultSecurityKey = []byte{}

Ajit Jagtap's avatar
Ajit Jagtap committed
var mutex = &sync.Mutex{}
var (
	// NumberOfReads Collects Number of Reads
	NumberOfReads = 0
	// NumberOfWrites Collects Number of Writes
	NumberOfWrites = 0
Ajit Jagtap's avatar
Ajit Jagtap committed
	// Fastcache Holds Cache for queries
	Fastcache cachemdl.FastCacheHelper
	// NumberOfReadsWithoutSecurity Collects Number of Reads without Security
	NumberOfReadsWithoutSecurity = 0
	// NumberOfWritesWithoutSecurity Collects Number of Writes without Security
	NumberOfWritesWithoutSecurity = 0
Ajit Jagtap's avatar
Ajit Jagtap committed
)

// GetDataDAO will return query data
func GetDataDAO(filePath, query string, isCachable bool, cacheTime time.Duration, rs gjson.Result) (gjson.Result, error) {
Ajit Jagtap's avatar
Ajit Jagtap committed

	if rs.Raw != "" {
		rs = rs.Get(query)
		return rs, nil
	}
	if isCachable {
Ajit Jagtap's avatar
Ajit Jagtap committed
		data, found := Fastcache.Get(filePath + query)
		go statemdl.UpdateGlobalServiceCacheState(found)
Ajit Jagtap's avatar
Ajit Jagtap committed
		if errormdl.CheckBool(found) {
Ajit Jagtap's avatar
Ajit Jagtap committed
			if errormdl.CheckBool1(ok) {
				return val, nil
			}
			return gjson.Result{}, nil
Ajit Jagtap's avatar
Ajit Jagtap committed
		}
	}
	byteData, err := getDataFromFDB(filePath)
	if errormdl.CheckErr(err) != nil {
		return gjson.Result{}, errormdl.CheckErr(err)
	}
	if query == constantmdl.STAR {
		rs = gjson.ParseBytes(byteData)
	} else {
		rs = gjson.ParseBytes(byteData).Get(query)
	}
	if isCachable {
		Fastcache.SetWithExpiration(filePath+query, rs, time.Second*cacheTime)
Ajit Jagtap's avatar
Ajit Jagtap committed
	}
	return rs, nil
}

//GetDataFromFDB gets data from FDB
func getDataFromFDB(filePath string) ([]byte, error) {
	//Following checking will be done for the provided file path, which will let us know
	// whether the file is Read only/Write only/Update only
	mutex.Lock()
	NumberOfReads = NumberOfReads + 1
	mutex.Unlock()

	data, err := filemdl.ReadFile(filePath)
	if errormdl.CheckErr(err) != nil {
		loggermdl.LogError(err)
	}
Roshan Patil's avatar
Roshan Patil committed
	if securityRequired {
		keyBytes, hashError := GetKeyWithFileNameAndDefaultKey(filePath)
		if errormdl.CheckErr1(hashError) != nil {
			return nil, errormdl.CheckErr1(hashError)
		}
		decryptedData, decryptionError := securitymdl.AESDecrypt(data, keyBytes)
		if errormdl.CheckErr2(decryptionError) != nil {
			return nil, errormdl.CheckErr2(decryptionError)
		}
		decompressedData, decompressError := filemdl.UnZipBytes(decryptedData)
		if errormdl.CheckErr3(decompressError) != nil {
			return nil, errormdl.CheckErr3(decompressError)
		}
		return decompressedData, nil
	}
Ajit Jagtap's avatar
Ajit Jagtap committed
	return data, err
}
Roshan Patil's avatar
Roshan Patil committed

// SaveDataToFDB saves the data in FDB
func SaveDataToFDB(filePath string, data []byte, makeDir, createBackup bool) error {
	mutex.Lock()
	NumberOfWrites = NumberOfWrites + 1
	mutex.Unlock()

Roshan Patil's avatar
Roshan Patil committed
	if securityRequired {

		keyBytes, hashError := GetKeyWithFileNameAndDefaultKey(filePath)
		if errormdl.CheckErr(hashError) != nil {
			return errormdl.CheckErr(hashError)
		}
		compressedText, compressionError := filemdl.ZipBytes(data)
		if errormdl.CheckErr2(compressionError) != nil {
			return errormdl.CheckErr2(compressionError)
		}
		encryptedData, encryptionError := securitymdl.AESEncrypt(compressedText, keyBytes)
		if errormdl.CheckErr1(encryptionError) != nil {
			return errormdl.CheckErr1(encryptionError)
		}
		saveError := filemdl.GetInstance().Save(filePath, encryptedData, makeDir, createBackup)
		return saveError
	}
Roshan Patil's avatar
Roshan Patil committed

	saveError := filemdl.GetInstance().Save(filePath, data, makeDir, createBackup)
	if errormdl.CheckErr(saveError) != nil {
		return errormdl.CheckErr(saveError)
	}
	// TODO: Delete file related entries from cacahe entries
	return nil
}
// SaveInterfaceDataToFDB saves the data in FDB
func SaveInterfaceDataToFDB(filePath string, interfaceData interface{}, makeDir, createBackup bool) error {
	mutex.Lock()
	NumberOfWrites = NumberOfWrites + 1
	mutex.Unlock()

	data, marshalError := ffjson.Marshal(interfaceData)
	if errormdl.CheckErr(marshalError) != nil {
		loggermdl.LogError(marshalError)
		return marshalError
	}
	if securityRequired {

		keyBytes, hashError := GetKeyWithFileNameAndDefaultKey(filePath)
		if errormdl.CheckErr(hashError) != nil {
			return errormdl.CheckErr(hashError)
		}
		compressedText, compressionError := filemdl.ZipBytes(data)
		if errormdl.CheckErr2(compressionError) != nil {
			return errormdl.CheckErr2(compressionError)
		}
		encryptedData, encryptionError := securitymdl.AESEncrypt(compressedText, keyBytes)
		if errormdl.CheckErr1(encryptionError) != nil {
			return errormdl.CheckErr1(encryptionError)
		}
		saveError := filemdl.GetInstance().Save(filePath, encryptedData, makeDir, createBackup)
		return saveError
	}

	saveError := filemdl.GetInstance().Save(filePath, data, makeDir, createBackup)
	if errormdl.CheckErr(saveError) != nil {
		return errormdl.CheckErr(saveError)
	}
	// TODO: Delete file related entries from cacahe entries
	return nil
}

//EnableSecurity Set remote path for receiving files if not found at local
func EnableSecurity(key []byte, initializationVector string) {
	securitymdl.SetSecurityConfig(key, initializationVector)
	defaultSecurityKey = key
	securityRequired = true
}

//DisableSecurity disables security
func DisableSecurity() {
	securityRequired = false
}

//GetSecurityStatus get status of security flag
func GetSecurityStatus() bool {
	return securityRequired
}

Roshan Patil's avatar
Roshan Patil committed
// GetKeyWithFileNameAndDefaultKey generates key using file name + Default key
func GetKeyWithFileNameAndDefaultKey(filePath string) ([]byte, error) {
	fileName := filepath.Base(filePath)
	fileNameBytes := []byte(fileName)
	fileNameBytes = append(fileNameBytes, defaultSecurityKey...)
	keyBytes, getHashError := hashmdl.Get128BitHash(fileNameBytes)
	if errormdl.CheckErr(getHashError) != nil {
		return nil, errormdl.CheckErr(getHashError)
	}
	return keyBytes[:], nil
}

//AppendDataToFDB apppends data to FDB
func AppendDataToFDB(filePath string, data []byte, createBackup bool) error {
	saveError := filemdl.GetInstance().Save(filePath, data, false, createBackup)
	return saveError
}

// SoftDeleteFileFromFDB rename file as per timestamp
func SoftDeleteFileFromFDB(filePath string) error {
	t := time.Now()
	newFilePath := filePath + "_deleted_" + t.Format("20060102150405")
	err := filemdl.RenameFile(filePath, newFilePath)
	return err
}

// HardDeleteFileFromFDB permanantly delete file from fdb
func HardDeleteFileFromFDB(filePath string) error {
	err := filemdl.DeleteFile(filePath)
	return err
}

//GetDataFromFDBWithoutSecurity gets data from FDB
func GetDataFromFDBWithoutSecurity(filePath string) ([]byte, error) {
	//Following checking will be done for the provided file path, which will let us know
	// whether the file is Read only/Write only/Update only
	mutex.Lock()
	NumberOfReadsWithoutSecurity = NumberOfReadsWithoutSecurity + 1
	mutex.Unlock()
	data, err := filemdl.ReadFile(filePath)
	if errormdl.CheckErr(err) != nil {
		// if !downloadFromInternet {
		return nil, errormdl.CheckErr(err)
		// }
		// if hostAddressForDataFiles == "" {
		// 	loggermdl.LogError("Call dalhelper.SetRemoteHostPath(remoteHost) to set remote file path ")
		// 	return nil, errormdl.CheckErr(err)
		// }
		// relativeFilePath := strings.SplitAfter(filePath, splitString)
		// remotePath := hostAddressForDataFiles + relativeFilePath[1]
		// resp, httpError := http.Get(remotePath)
		// if httpError != nil || (resp != nil && resp.StatusCode == 404) {
		// 	return nil, httpError
		// }
		// data, readError := ioutil.ReadAll(resp.Body)
		// if errormdl.CheckErr1(readError) != nil {
		// 	loggermdl.LogError("Error while reading data from response body ", readError)
		// 	return nil, errormdl.CheckErr1(readError)
		// }
		// defer resp.Body.Close()
		// saveError := SaveDataToFDB(filePath, data, true, false)
		// return data, saveError
	}
	return data, err
}

//SaveDataToFDBWithoutSecurity saves data to FDB
func SaveDataToFDBWithoutSecurity(filePath string, data []byte, makeDir, createBackup bool) error {
	mutex.Lock()
	NumberOfWritesWithoutSecurity = NumberOfWritesWithoutSecurity + 1
	mutex.Unlock()
	saveError := filemdl.GetInstance().Save(filePath, data, makeDir, createBackup)
	return saveError
}

// // EnableRemoteFileDownload Set remote address and enable file download from internet
// func EnableRemoteFileDownload(remoteHostAddress, pathSplitString string) {
// 	hostAddressForDataFiles = remoteHostAddress
// 	splitString = pathSplitString
// 	downloadFromInternet = true
// }

// // DisableRemoteFileDownload disables  file download from internet
// func DisableRemoteFileDownload() {
// 	hostAddressForDataFiles = ""
// 	splitString = ""
// 	downloadFromInternet = false
// }

// // GetRemoteFileDownloadStatus get status of file download from internet
// func GetRemoteFileDownloadStatus() bool {
// 	return downloadFromInternet
// }
Roshan Patil's avatar
Roshan Patil committed

// SaveDataToFDBWithoutQueue saves the data in FDB without file queueing
func SaveDataToFDBWithoutQueue(filePath string, data []byte, makeDir, createBackup bool) error {
	mutex.Lock()
	NumberOfWrites = NumberOfWrites + 1
	mutex.Unlock()

Roshan Patil's avatar
Roshan Patil committed
	if securityRequired {
		keyBytes, hashError := GetKeyWithFileNameAndDefaultKey(filePath)
		if errormdl.CheckErr(hashError) != nil {
			return errormdl.CheckErr(hashError)
		}
		compressedText, compressionError := filemdl.ZipBytes(data)
		if errormdl.CheckErr2(compressionError) != nil {
			return errormdl.CheckErr2(compressionError)
		}
		encryptedData, encryptionError := securitymdl.AESEncrypt(compressedText, keyBytes)
		if errormdl.CheckErr1(encryptionError) != nil {
			return errormdl.CheckErr1(encryptionError)
		}
		saveError := filemdl.WriteFile(filePath, encryptedData, makeDir, createBackup)
		return saveError
	}
Roshan Patil's avatar
Roshan Patil committed

	saveError := filemdl.WriteFile(filePath, data, makeDir, createBackup)
	if errormdl.CheckErr(saveError) != nil {
		return errormdl.CheckErr(saveError)
	}
	// TODO: Delete file related entries from cacahe entries
	return nil
}

//AppendDataToFDBWithoutQueue apppends data to FDB without file queueing
func AppendDataToFDBWithoutQueue(filePath string, data []byte, createBackup bool) error {
	saveError := filemdl.WriteFile(filePath, data, false, createBackup)
	return saveError
}