github.com/sentienttechnologies/studio-go-runner@v0.0.0-20201118202441-6d21f2ced8ee/internal/runner/envelope.go (about) 1 // Copyright 2020 (c) Cognizant Digital Business, Evolutionary AI. All rights reserved. Issued under the Apache 2.0 License. 2 3 package runner 4 5 import ( 6 "encoding/json" 7 8 "github.com/go-stack/stack" 9 "github.com/jjeffery/kv" 10 ) 11 12 // This file contains the implementation of an envelop message that will be used to 13 // add the chrome for holding StudioML requests and their respective signature attachment 14 // and encryption wrappers. 15 16 type OpenExperiment struct { 17 Status string `json:"status"` 18 PythonVer string `json:"pthonver"` 19 } 20 21 // Message contains any clear text fields and either an an encrypted payload or clear text 22 // payloads as a Request. 23 type Message struct { 24 Experiment OpenExperiment `json:"experiment"` 25 TimeAdded float64 `json:"time_added"` 26 ExperimentLifetime string `json:"experiment_lifetime"` 27 Resource Resource `json:"resources_needed"` 28 Payload string `json:"payload"` 29 Fingerprint string `json:"fingerprint"` 30 Signature string `json:"signature"` 31 } 32 33 // Request marshals the requests made by studioML under which all of the other 34 // meta data can be found 35 type Envelope struct { 36 Message Message `json:"message"` 37 } 38 39 // IsEnvelop is used to test if a JSON payload is indeed present 40 func IsEnvelope(msg []byte) (isEnvelope bool, err kv.Error) { 41 fields := map[string]interface{}{} 42 if errGo := json.Unmarshal(msg, &fields); errGo != nil { 43 return false, kv.Wrap(errGo).With("stack", stack.Trace().TrimRuntime()) 44 } 45 // Examine the fields and see that we have a message 46 if _, isPresent := fields["message"]; !isPresent { 47 return false, kv.NewError("'message' missing").With("stack", stack.Trace().TrimRuntime()) 48 } 49 message, isOK := fields["message"].(map[string]interface{}) 50 if !isOK { 51 return false, kv.NewError("'message.payload' invalid").With("stack", stack.Trace().TrimRuntime()) 52 } 53 if _, isPresent := message["payload"]; !isPresent { 54 return false, kv.NewError("'message.payload' missing").With("stack", stack.Trace().TrimRuntime()) 55 56 } 57 return true, nil 58 } 59 60 // UnmarshalRequest takes an encoded StudioML envelope and extracts it 61 // into go data structures used by the go runner. 62 // 63 func UnmarshalEnvelope(data []byte) (e *Envelope, err kv.Error) { 64 e = &Envelope{} 65 if errGo := json.Unmarshal(data, e); errGo != nil { 66 return nil, kv.Wrap(errGo).With("stack", stack.Trace().TrimRuntime()) 67 } 68 return e, nil 69 } 70 71 // Marshal takes the go data structure used to define a StudioML experiment envelope 72 // and serializes it as json to the byte array 73 // 74 func (e *Envelope) Marshal() ([]byte, error) { 75 return json.Marshal(e) 76 }