324 lines
7.7 KiB
Go
324 lines
7.7 KiB
Go
/*
|
|
|--------------------------------------------------------------------------
|
|
| Manifest
|
|
|--------------------------------------------------------------------------
|
|
|
|
|
| Name:
|
|
| - Retriever
|
|
|
|
|
| Purpose:
|
|
| - Retrieve data from supported resource providers through a unified
|
|
| retrieval interface.
|
|
|
|
|
| Guideline:
|
|
| - Use registered providers to retrieve resources.
|
|
| - Use resource identifiers to resolve providers.
|
|
| - Use path or fields selection for partial retrieval.
|
|
| - Path and fields are mutually exclusive.
|
|
|
|
|
| Example:
|
|
| - ObrimRetriever("json", map[string]any{"resource": "metadata"})
|
|
| - ObrimRetriever("json", map[string]any{
|
|
| "resource": "metadata",
|
|
| "path": "application.name",
|
|
| })
|
|
|
|
|
|--------------------------------------------------------------------------
|
|
*/
|
|
|
|
/*
|
|
|--------------------------------------------------------------------------
|
|
| Credit
|
|
|--------------------------------------------------------------------------
|
|
|
|
|
| Contributor:
|
|
| - Rajon Ahmed
|
|
| - Scionite
|
|
|
|
|
|--------------------------------------------------------------------------
|
|
*/
|
|
|
|
package retriever
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"go/module/essential/visible/service/helper/log"
|
|
"go/module/essential/visible/service/helper/status"
|
|
)
|
|
|
|
// ObrimRetrieverResponse represents the standardized utility response.
|
|
type ObrimRetrieverResponse struct {
|
|
Status bool `json:"status"`
|
|
Code string `json:"code"`
|
|
Payload any `json:"payload"`
|
|
}
|
|
|
|
// ObrimRetrieverJsonProviderRegistry stores registered JSON providers.
|
|
var ObrimRetrieverJsonProviderRegistry = map[string]any{}
|
|
|
|
// ObrimRetrieverDbProviderRegistry stores registered database providers.
|
|
var ObrimRetrieverDbProviderRegistry = map[string]any{}
|
|
|
|
// ObrimRetriever retrieves data using a unified retrieval interface.
|
|
func ObrimRetriever(retrievalType string, config map[string]any) map[string]any {
|
|
status.ObrimStatus("INFO", "Retriever started.")
|
|
log.ObrimLog("INIT", "Retriever execution started.")
|
|
|
|
if !obrimRetrieverValidateType(retrievalType) {
|
|
return obrimRetrieverBuildResponse(false, "FAILED_UNSUPPORTED_TYPE", nil)
|
|
}
|
|
|
|
if !obrimRetrieverValidateConfig(retrievalType, config) {
|
|
return obrimRetrieverBuildResponse(false, "FAILED_INVALID_CONFIGURATION", nil)
|
|
}
|
|
|
|
switch retrievalType {
|
|
case "json":
|
|
return obrimRetrieverJson(config)
|
|
|
|
case "db":
|
|
return obrimRetrieverDb(config)
|
|
|
|
default:
|
|
return obrimRetrieverBuildResponse(false, "FAILED_UNSUPPORTED_TYPE", nil)
|
|
}
|
|
}
|
|
|
|
// ObrimRetrieverJsonRegister registers a JSON provider.
|
|
func ObrimRetrieverJsonRegister(resource string, provider any) {
|
|
ObrimRetrieverJsonProviderRegistry[resource] = provider
|
|
}
|
|
|
|
// ObrimRetrieverDbRegister registers a database provider.
|
|
func ObrimRetrieverDbRegister(resource string, provider any) {
|
|
ObrimRetrieverDbProviderRegistry[resource] = provider
|
|
}
|
|
|
|
// obrimRetrieverValidateType validates the requested retrieval type.
|
|
func obrimRetrieverValidateType(retrievalType string) bool {
|
|
switch retrievalType {
|
|
case "json", "db":
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
// obrimRetrieverValidateConfig validates configuration by retrieval type.
|
|
func obrimRetrieverValidateConfig(retrievalType string, config map[string]any) bool {
|
|
switch retrievalType {
|
|
case "json":
|
|
return obrimRetrieverJsonValidate(config)
|
|
|
|
case "db":
|
|
return obrimRetrieverDbValidate(config)
|
|
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
// obrimRetrieverResolveProvider resolves a provider by resource identifier.
|
|
func obrimRetrieverResolveProvider(
|
|
retrievalType string,
|
|
resource string,
|
|
) (any, bool) {
|
|
switch retrievalType {
|
|
case "json":
|
|
provider, exists := ObrimRetrieverJsonProviderRegistry[resource]
|
|
return provider, exists
|
|
|
|
case "db":
|
|
provider, exists := ObrimRetrieverDbProviderRegistry[resource]
|
|
return provider, exists
|
|
|
|
default:
|
|
return nil, false
|
|
}
|
|
}
|
|
|
|
// obrimRetrieverBuildResponse builds a standardized response.
|
|
func obrimRetrieverBuildResponse(
|
|
success bool,
|
|
code string,
|
|
payload any,
|
|
) map[string]any {
|
|
return map[string]any{
|
|
"status": success,
|
|
"code": code,
|
|
"payload": payload,
|
|
}
|
|
}
|
|
|
|
// obrimRetrieverJson processes JSON retrieval requests.
|
|
func obrimRetrieverJson(config map[string]any) map[string]any {
|
|
resource, _ := config["resource"].(string)
|
|
|
|
provider, exists := obrimRetrieverResolveProvider("json", resource)
|
|
if !exists {
|
|
return obrimRetrieverBuildResponse(false, "FAILED_RESOURCE_NOT_FOUND", nil)
|
|
}
|
|
|
|
data, err := obrimRetrieverJsonResource(provider)
|
|
if err != nil {
|
|
return obrimRetrieverBuildResponse(false, "FAILED_RESOURCE_NOT_FOUND", nil)
|
|
}
|
|
|
|
_, hasPath := config["path"]
|
|
_, hasFields := config["fields"]
|
|
|
|
if hasPath {
|
|
return obrimRetrieverJsonPath(data, config)
|
|
}
|
|
|
|
if hasFields {
|
|
return obrimRetrieverJsonFields(data, config)
|
|
}
|
|
|
|
return obrimRetrieverBuildResponse(
|
|
true,
|
|
"SUCCESS_RESOURCE",
|
|
map[string]any{
|
|
"data": data,
|
|
},
|
|
)
|
|
}
|
|
|
|
// obrimRetrieverJsonResource retrieves a complete resource payload.
|
|
func obrimRetrieverJsonResource(provider any) (any, error) {
|
|
switch value := provider.(type) {
|
|
case func() (any, error):
|
|
return value()
|
|
|
|
case func() any:
|
|
return value(), nil
|
|
|
|
default:
|
|
return nil, fmt.Errorf("invalid provider")
|
|
}
|
|
}
|
|
|
|
// obrimRetrieverJsonPath retrieves a value using dot notation.
|
|
func obrimRetrieverJsonPath(
|
|
data any,
|
|
config map[string]any,
|
|
) map[string]any {
|
|
path, _ := config["path"].(string)
|
|
|
|
value, found := obrimRetrieverResolvePath(data, path)
|
|
if !found {
|
|
return obrimRetrieverBuildResponse(false, "FAILED_PATH_NOT_FOUND", nil)
|
|
}
|
|
|
|
return obrimRetrieverBuildResponse(
|
|
true,
|
|
"SUCCESS_PATH",
|
|
map[string]any{
|
|
"data": value,
|
|
},
|
|
)
|
|
}
|
|
|
|
// obrimRetrieverJsonFields retrieves multiple values using field selection.
|
|
func obrimRetrieverJsonFields(
|
|
data any,
|
|
config map[string]any,
|
|
) map[string]any {
|
|
fields, ok := config["fields"].([]string)
|
|
if !ok {
|
|
rawFields, castOk := config["fields"].([]any)
|
|
if !castOk {
|
|
return obrimRetrieverBuildResponse(false, "FAILED_INVALID_CONFIGURATION", nil)
|
|
}
|
|
|
|
fields = make([]string, 0, len(rawFields))
|
|
|
|
for _, field := range rawFields {
|
|
fieldString, stringOk := field.(string)
|
|
if !stringOk {
|
|
return obrimRetrieverBuildResponse(false, "FAILED_INVALID_CONFIGURATION", nil)
|
|
}
|
|
|
|
fields = append(fields, fieldString)
|
|
}
|
|
}
|
|
|
|
result := map[string]any{}
|
|
|
|
for _, field := range fields {
|
|
value, found := obrimRetrieverResolvePath(data, field)
|
|
if !found {
|
|
return obrimRetrieverBuildResponse(false, "FAILED_FIELD_NOT_FOUND", nil)
|
|
}
|
|
|
|
result[field] = value
|
|
}
|
|
|
|
return obrimRetrieverBuildResponse(
|
|
true,
|
|
"SUCCESS_FIELDS",
|
|
map[string]any{
|
|
"data": result,
|
|
},
|
|
)
|
|
}
|
|
|
|
// obrimRetrieverJsonValidate validates JSON configuration.
|
|
func obrimRetrieverJsonValidate(config map[string]any) bool {
|
|
resource, exists := config["resource"]
|
|
if !exists {
|
|
return false
|
|
}
|
|
|
|
resourceString, ok := resource.(string)
|
|
if !ok || strings.TrimSpace(resourceString) == "" {
|
|
return false
|
|
}
|
|
|
|
_, hasPath := config["path"]
|
|
_, hasFields := config["fields"]
|
|
|
|
if hasPath && hasFields {
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
// obrimRetrieverDb processes database retrieval requests.
|
|
func obrimRetrieverDb(config map[string]any) map[string]any {
|
|
return obrimRetrieverBuildResponse(false, "FAILED_NOT_IMPLEMENTED", nil)
|
|
}
|
|
|
|
// obrimRetrieverDbValidate validates database configuration.
|
|
func obrimRetrieverDbValidate(config map[string]any) bool {
|
|
return true
|
|
}
|
|
|
|
// obrimRetrieverResolvePath resolves a dot-notation path.
|
|
func obrimRetrieverResolvePath(data any, path string) (any, bool) {
|
|
if strings.TrimSpace(path) == "" {
|
|
return nil, false
|
|
}
|
|
|
|
current := data
|
|
|
|
for _, segment := range strings.Split(path, ".") {
|
|
object, ok := current.(map[string]any)
|
|
if !ok {
|
|
return nil, false
|
|
}
|
|
|
|
value, exists := object[segment]
|
|
if !exists {
|
|
return nil, false
|
|
}
|
|
|
|
current = value
|
|
}
|
|
|
|
return current, true
|
|
}
|