/* |-------------------------------------------------------------------------- | Description |-------------------------------------------------------------------------- | | Name: | - Handler | | Purpose: | - Provides access to embedded software metadata resources through | resource-specific retrieval and parsing logic. | |-------------------------------------------------------------------------- */ /* |-------------------------------------------------------------------------- | Credit |-------------------------------------------------------------------------- | | Contributor: | - Rajon Ahmed | - Blockonite | |-------------------------------------------------------------------------- */ package metadata import ( "embed" "encoding/json" "sync" "go/module/essential/visible/service/helper/retriever" ) // ObrimHandlerResource is the registered JSON resource identifier. const ObrimHandlerResource = "framework/metadata" // Success result codes. const ( ObrimHandlerCodeSuccessLoaded = "SUCCESS_RESOURCE_LOADED" ) // Failure result codes. const ( ObrimHandlerCodeFailureNotFound = "FAILURE_RESOURCE_NOT_FOUND" ObrimHandlerCodeFailureLoad = "FAILURE_RESOURCE_LOAD" ObrimHandlerCodeFailureParse = "FAILURE_RESOURCE_PARSE" ) // handlerResourceFile is the embedded JSON resource filename. const handlerResourceFile = "resource.json" // handlerEmbeddedResource stores the embedded JSON resource. // //go:embed resource.json var handlerEmbeddedResource embed.FS // obrimHandlerCacheMutex protects the resource cache. var obrimHandlerCacheMutex sync.RWMutex // obrimHandlerCachedResource stores the parsed resource for the application lifetime. var obrimHandlerCachedResource map[string]any // ObrimHandlerPayload defines the successful payload structure. type ObrimHandlerPayload struct { Resource string `json:"resource"` Data map[string]any `json:"data"` } // ObrimHandlerOutput defines the standardized utility output. type ObrimHandlerOutput struct { Status bool `json:"status"` Code string `json:"code"` Payload *ObrimHandlerPayload `json:"payload"` } // ObrimHandlerJson registers the JSON handler callback with Retriever. func ObrimHandlerJson() { retriever.ObrimRetrieverJsonRegister( ObrimHandlerResource, obrimHandlerFetch, ) } // obrimHandler is the internal handler entry function. func obrimHandler() ObrimHandlerOutput { return obrimHandlerFetch() } // obrimHandlerFetch loads, parses, caches, and returns the complete JSON resource. func obrimHandlerFetch() ObrimHandlerOutput { if cached, ok := obrimHandlerCache(); ok { return obrimHandlerOutput( true, ObrimHandlerCodeSuccessLoaded, cached, ) } data, err := obrimHandlerLoad() if err != nil { return obrimHandlerOutput( false, ObrimHandlerCodeFailureLoad, nil, ) } resource, err := obrimHandlerParse(data) if err != nil { return obrimHandlerOutput( false, ObrimHandlerCodeFailureParse, nil, ) } obrimHandlerCache(resource) return obrimHandlerOutput( true, ObrimHandlerCodeSuccessLoaded, resource, ) } // obrimHandlerCache retrieves or stores the parsed JSON resource cache. func obrimHandlerCache(resource ...map[string]any) (map[string]any, bool) { obrimHandlerCacheMutex.Lock() defer obrimHandlerCacheMutex.Unlock() switch len(resource) { case 0: if obrimHandlerCachedResource == nil { return nil, false } return obrimHandlerCachedResource, true default: obrimHandlerCachedResource = resource[0] return obrimHandlerCachedResource, true } } // obrimHandlerEmbed returns the embedded JSON resource filesystem. func obrimHandlerEmbed() embed.FS { return handlerEmbeddedResource } // obrimHandlerLoad loads the embedded JSON resource. func obrimHandlerLoad() ([]byte, error) { return obrimHandlerEmbed().ReadFile(handlerResourceFile) } // obrimHandlerParse parses the embedded JSON resource. func obrimHandlerParse(data []byte) (map[string]any, error) { resource := make(map[string]any) if err := json.Unmarshal(data, &resource); err != nil { return nil, err } return resource, nil } // obrimHandlerOutput builds the standardized utility output. func obrimHandlerOutput( status bool, code string, resource map[string]any, ) ObrimHandlerOutput { if !status || resource == nil { return ObrimHandlerOutput{ Status: false, Code: code, Payload: nil, } } return ObrimHandlerOutput{ Status: true, Code: code, Payload: &ObrimHandlerPayload{ Resource: ObrimHandlerResource, Data: resource, }, } }