@@ -481,7 +481,7 @@ func deleteJunkOpsWorkflow(ctx context.Context, workflowHealth WorkflowHealth) e
481481
482482 if len (workflows ) == 0 {
483483 //log.Printf("[DEBUG] Couldn't find any workflow named SHUFFLE_INTERNAL_OPS_WORKFLOW")
484- return errors .New ("Failed finding workflow named SHUFFLE_INTERNAL_OPS_WORKFLOW " )
484+ return errors .New ("Failed finding workflow named Ops Dashboard Workflow " )
485485 }
486486
487487 //log.Printf("[DEBUG] Found %d workflows named SHUFFLE_INTERNAL_OPS_WORKFLOW: ", len(workflows))
@@ -732,6 +732,7 @@ func RunOpsHealthCheck(resp http.ResponseWriter, request *http.Request) {
732732 log .Printf ("[ERROR] Failed running app health check: %s" , err )
733733 }
734734
735+ appHealth .Result = ""
735736 openapiAppHealthChannel <- appHealth
736737 errorChannel <- err
737738 }()
@@ -747,9 +748,33 @@ func RunOpsHealthCheck(resp http.ResponseWriter, request *http.Request) {
747748 errorChannel <- err
748749 }()
749750
751+ datastoreHealthChannel := make (chan DatastoreHealth )
752+ go func () {
753+ datastoreHealth , err := RunOpsDatastore (apiKey , orgId )
754+ if err != nil {
755+ log .Printf ("[ERROR] Failed running datastore health check: %s" , err )
756+ }
757+
758+ datastoreHealthChannel <- datastoreHealth
759+ errorChannel <- err
760+ }()
761+
762+ fileHealthChannel := make (chan FileHealth )
763+ go func () {
764+ fileHealth , err := RunOpsFile (apiKey , orgId )
765+ if err != nil {
766+ log .Printf ("[ERROR] Failed running file health check: %s" , err )
767+ }
768+
769+ fileHealthChannel <- fileHealth
770+ errorChannel <- err
771+ }()
772+
750773 // Use channel for getting RunOpsWorkflow function results
751774 platformHealth .Apps = <- openapiAppHealthChannel
752775 platformHealth .PythonApps = <- pythonAppHealthChannel
776+ platformHealth .Datastore = <- datastoreHealthChannel
777+ platformHealth .FileOps = <- fileHealthChannel
753778 }
754779
755780 platformHealth .Workflows = <- workflowHealthChannel
@@ -1769,6 +1794,7 @@ func InitOpsWorkflow(apiKey string, OrgId string) (string, error) {
17691794 workflowData .Public = false
17701795 workflowData .Status = ""
17711796 workflowData .Name = "Ops Dashboard Workflow"
1797+ workflowData .ID = "shuffler-doti-ohea-lthc-heckworkflow"
17721798 workflowData .Hidden = true
17731799 workflowData .BackgroundProcessing = true
17741800
@@ -1958,6 +1984,229 @@ func InitOpsWorkflow(apiKey string, OrgId string) (string, error) {
19581984 return workflowData .ID , nil
19591985}
19601986
1987+ // Create datastore
1988+ // read it
1989+ // delete it
1990+ func RunOpsDatastore (apikey , orgId string ) (DatastoreHealth , error ) {
1991+ baseUrl := os .Getenv ("SHUFFLE_CLOUDRUN_URL" )
1992+ if len (baseUrl ) == 0 {
1993+ baseUrl = "https://shuffler.io"
1994+ }
1995+
1996+ if project .Environment == "onprem" {
1997+ baseUrl = "http://localhost:5001"
1998+ }
1999+
2000+ datastoreHealth := DatastoreHealth {
2001+ Create : false ,
2002+ Read : false ,
2003+ Result : "" ,
2004+ Delete : false ,
2005+ }
2006+
2007+ // create datastore entry
2008+ PAYLOAD := `{"key": "SHUFFLE_HEALTH_CHECK", "value": "yesy", "category": "SHUFFLE_HEALTH_CHECK"}`
2009+ url := fmt .Sprintf ("%s/api/v1/orgs/%s/set_cache" , baseUrl , orgId )
2010+ req , err := http .NewRequest ("POST" , url , bytes .NewBuffer ([]byte (PAYLOAD )))
2011+ if err != nil {
2012+ log .Printf ("[ERROR] Failed to create request (%s) for set_cache %s" , url , err )
2013+ return datastoreHealth , err
2014+ }
2015+
2016+ req .Header .Set ("Authorization" , "Bearer " + apikey )
2017+ req .Header .Set ("Content-Type" , "application/json" )
2018+
2019+ // Follow proxy and stuff
2020+ client := GetExternalClient (baseUrl )
2021+ resp , err := client .Do (req )
2022+ resp .Body .Close ()
2023+ if err != nil {
2024+ log .Printf ("[ERROR] Failed to send request (%s) for set_cache %s" , url , err )
2025+ return datastoreHealth , err
2026+ }
2027+
2028+ datastoreHealth .Create = true
2029+ //read datastore entry
2030+ PAYLOAD = fmt .Sprintf (`{"org_id": "%s", "key": "SHUFFLE_HEALTH_CHECK"}` , orgId )
2031+ url = fmt .Sprintf ("%s/api/v1/orgs/%s/get_cache" , baseUrl , orgId )
2032+ req , err = http .NewRequest ("POST" , url , bytes .NewBuffer ([]byte (PAYLOAD )))
2033+ if err != nil {
2034+ log .Printf ("[ERROR] Failed to create request (%s) for get_cache: %s" , url , err )
2035+ return datastoreHealth , err
2036+ }
2037+
2038+ req .Header .Set ("Authorization" , "Bearer " + apikey )
2039+ req .Header .Set ("Content-Type" , "application/json" )
2040+
2041+ resp , err = client .Do (req )
2042+ if err != nil {
2043+ log .Printf ("[ERROR] Failed to send request to get_cache: %s" , err )
2044+ return datastoreHealth , err
2045+ }
2046+
2047+ dataStoreValue , err := io .ReadAll (resp .Body )
2048+ if err != nil {
2049+ log .Printf ("[ERROR] Failed to read datastore return value: %s" , err )
2050+ }
2051+
2052+ datastoreHealth .Result = string (dataStoreValue )
2053+ resp .Body .Close ()
2054+ datastoreHealth .Read = true
2055+
2056+ // Delete
2057+ PAYLOAD = fmt .Sprintf (`{"org_id": "%s", "key": "SHUFFLE_HEALTH_CHECK"}` , orgId )
2058+ url = fmt .Sprintf ("%s/api/v1/orgs/%s/delete_cache" , baseUrl , orgId )
2059+ req , err = http .NewRequest ("POST" , url , bytes .NewBuffer ([]byte (PAYLOAD )))
2060+ if err != nil {
2061+ log .Printf ("[ERROR] Failed to create request (%s) for delete_key: %s" , url , err )
2062+ return datastoreHealth , err
2063+ }
2064+
2065+ req .Header .Set ("Authorization" , "Bearer " + apikey )
2066+ req .Header .Set ("Content-Type" , "application/json" )
2067+
2068+ resp , err = client .Do (req )
2069+ if err != nil {
2070+ log .Printf ("[ERROR] Failed to send request to delete_key: %s" , err )
2071+ return datastoreHealth , err
2072+ }
2073+
2074+ datastoreHealth .Delete = true
2075+ return datastoreHealth , nil
2076+ }
2077+
2078+ func RunOpsFile (apikey , orgId string ) (FileHealth , error ) {
2079+ baseUrl := os .Getenv ("SHUFFLE_CLOUDRUN_URL" )
2080+ if len (baseUrl ) == 0 {
2081+ baseUrl = "https://shuffler.io"
2082+ }
2083+
2084+ if project .Environment == "onprem" {
2085+ baseUrl = "http://localhost:5001"
2086+ }
2087+
2088+ fileHealth := FileHealth {
2089+ Create : false ,
2090+ FileId : "" ,
2091+ Upload : false ,
2092+ Delete : false ,
2093+ }
2094+
2095+ PAYLOAD := fmt .Sprintf (`{"filename": "SHUFFLE_HEALTH_TEST_FILE", "org_id": "%s", "workflow_id": "global"}` , orgId )
2096+ url := fmt .Sprintf ("%s/api/v1/files/create" , baseUrl )
2097+
2098+ req , err := http .NewRequest ("POST" , url , bytes .NewBuffer ([]byte (PAYLOAD )))
2099+ if err != nil {
2100+ log .Printf ("[ERROR] Failed to create new request for create file(%s): %s" , url , err )
2101+ return fileHealth , err
2102+ }
2103+
2104+ req .Header .Set ("Authorization" , "Bearer " + apikey )
2105+ req .Header .Set ("Content-Type" , "application/json" )
2106+
2107+ var fileRespStruct struct {
2108+ Success bool `json:success`
2109+ Id string `json:id`
2110+ }
2111+
2112+ client := GetExternalClient (baseUrl )
2113+ resp , err := client .Do (req )
2114+ defer resp .Body .Close ()
2115+ if err != nil {
2116+ log .Printf ("[ERROR] Failed to send request (%s) for set_cache %s" , url , err )
2117+ return fileHealth , err
2118+ }
2119+
2120+ body , err := io .ReadAll (resp .Body )
2121+ if err != nil {
2122+ log .Printf ("[ERROR] Failed to read response body" )
2123+ return fileHealth , err
2124+ }
2125+
2126+
2127+ err = json .Unmarshal (body , & fileRespStruct )
2128+ if err != nil {
2129+ log .Printf ("[ERROR] Failed to unmarshal response" )
2130+ return fileHealth , err
2131+ }
2132+
2133+ fileHealth .Create = true
2134+ //Upload file
2135+ url = fmt .Sprintf ("%s/api/v1/files/%s/upload" , baseUrl , fileRespStruct .Id )
2136+ remoteUrl := "https://raw.githubusercontent.com/Shuffle/Shuffle/refs/heads/main/LICENSE"
2137+
2138+ resp , err = http .Get (remoteUrl )
2139+ if err != nil {
2140+ log .Printf ("[ERROR] Failed to fetch remote file: %s" , err )
2141+ return fileHealth , err
2142+ }
2143+
2144+ defer resp .Body .Close ()
2145+
2146+ var buf bytes.Buffer
2147+ w := multipart .NewWriter (& buf )
2148+ formFile , err := w .CreateFormFile ("shuffle_file" , "file.txt" )
2149+ if err != nil {
2150+ log .Printf ("[ERROR] Failed to create form file: %s" , err )
2151+ return fileHealth , err
2152+ }
2153+
2154+ if _ , err := io .Copy (formFile , resp .Body ); err != nil {
2155+ log .Printf ("[ERROR] Failed to copy remote file to form: %s" , err )
2156+ return fileHealth , err
2157+ }
2158+
2159+ w .Close ()
2160+ req , err = http .NewRequest ("POST" , url , & buf )
2161+ if err != nil {
2162+ log .Printf ("[ERROR] Failed to create upload request: %s" , err )
2163+ return fileHealth , err
2164+ }
2165+
2166+ req .Header .Set ("Authorization" , "Bearer " + apikey )
2167+ req .Header .Set ("Content-Type" , w .FormDataContentType ())
2168+ uploadResp , err := client .Do (req )
2169+ if err != nil {
2170+ log .Printf ("[ERROR] Upload request failed: %s" , err )
2171+ return fileHealth , err
2172+ }
2173+
2174+ defer uploadResp .Body .Close ()
2175+ if uploadResp .StatusCode != 200 {
2176+ log .Printf ("[ERROR] Failed to upload file, not 200 status code" )
2177+ return fileHealth , fmt .Errorf ("upload failed for file" )
2178+ }
2179+
2180+ log .Printf ("[INFO] Filed uploaded successfully to %s" , url )
2181+ fileHealth .FileId = fileRespStruct .Id
2182+ fileHealth .Upload = true
2183+ //Delete file
2184+ url = fmt .Sprintf ("%s/api/v1/files/%s?remove_metadata=true" , baseUrl , fileRespStruct .Id )
2185+ req , err = http .NewRequest ("DELETE" , url , nil )
2186+ if err != nil {
2187+ log .Printf ("[ERROR] Failed to create delete request: %s" , err )
2188+ return fileHealth , err
2189+ }
2190+
2191+ req .Header .Set ("Authorization" , "Bearer " + apikey )
2192+ resp , err = client .Do (req )
2193+ if err != nil {
2194+ log .Printf ("[ERROR] Failed to send delete request: %s" , err )
2195+ return fileHealth , err
2196+ }
2197+ defer resp .Body .Close ()
2198+
2199+ if resp .StatusCode != 200 {
2200+ log .Printf ("[ERROR] Failed to delete file, not 200 status code" )
2201+ return fileHealth , fmt .Errorf ("delete failed for file" )
2202+ }
2203+
2204+ log .Printf ("[INFO] File %s deleted successfully with metadata." , fileRespStruct .Id )
2205+ fileHealth .Delete = true
2206+
2207+ return fileHealth , nil
2208+ }
2209+
19612210func GetStaticWorkflowHealth (ctx context.Context , workflow Workflow ) (Workflow , []string , error ) {
19622211 orgUpdated := false
19632212 startnodeFound := false
0 commit comments