Documentation ¶
Index ¶
- Variables
- func GetStorage(r *http.Request) storage.Storage
- func IsDir(p string) bool
- func IsDirEmpty(dir string) bool
- func IsNewestSlangVersion(myVerStr string) (bool, string, error)
- func SetHub(ctx context.Context, h *Hub) context.Context
- func SetStorage(ctx context.Context, st *storage.Storage) context.Context
- type AuthHandleFunc
- type BasicAuth
- type ConnectedClient
- type Endpoint
- type Error
- type Hub
- type RunInstruction
- type RunState
- type Server
- func (s *Server) AddRedirect(path string, redirectTo string)
- func (s *Server) AddService(pathPrefix string, services *Service)
- func (s *Server) AddStaticServer(pathPrefix string, directory http.Dir)
- func (s *Server) AddWebsocket(path string)
- func (s *Server) Handler() http.Handler
- func (s *Server) Run() error
- type Service
- type SlangComponentLoader
- type Topic
- type UserID
Constants ¶
This section is empty.
Variables ¶
var ( SlangVersion string // Root defines a single instance of our user as we currently do not have // I use that to get the rest of the code to think about multi tenancy Root = &UserID{0} )
var DefinitionService = &Service{map[string]*Endpoint{ "/": {func(w http.ResponseWriter, r *http.Request) { st := GetStorage(r) type blueprintJSON struct { Def core.Blueprint `json:"def"` Type string `json:"type"` } type outJSON struct { Objects []blueprintJSON `json:"objects"` Status string `json:"status"` Error *Error `json:"error,omitempty"` } var dataOut outJSON var err error blueprints := make([]blueprintJSON, 0) opIds, err := st.List() if err == nil { builtinOpIds := elem.GetBuiltinIds() for _, opId := range builtinOpIds { blueprint, err := elem.GetBlueprint(opId) if err != nil { break } blueprints = append(blueprints, blueprintJSON{ Type: "elementary", Def: *blueprint, }) } if err == nil { for _, opId := range opIds { blueprint, err := st.Load(opId) if err != nil { continue } opType := "library" if st.IsSavedInWritableBackend(opId) { opType = "local" } blueprints = append(blueprints, blueprintJSON{ Type: opType, Def: *blueprint, }) } } } if err == nil { dataOut = outJSON{Status: "success", Objects: blueprints} } else { dataOut = outJSON{Status: "error", Error: &Error{Msg: err.Error(), Code: "E000X"}} } w.WriteHeader(200) err = writeJSON(w, dataOut) if err != nil { log.Print(err) } }}, "/def/": {func(w http.ResponseWriter, r *http.Request) { st := GetStorage(r) fail := func(err *Error) { sendFailure(w, &responseBad{err}) } if r.Method == "POST" { body, err := ioutil.ReadAll(r.Body) if err != nil { fail(&Error{Msg: err.Error(), Code: "E000X"}) return } var def core.Blueprint err = json.Unmarshal(body, &def) if err != nil { fail(&Error{Msg: err.Error(), Code: "E000X"}) return } _, err = st.Save(def) if err != nil { fail(&Error{Msg: err.Error(), Code: "E000X"}) return } sendSuccess(w, nil) } }}, }}
var InstanceService = &Service{map[string]*Endpoint{ "/": {func(w http.ResponseWriter, r *http.Request) { type outJSON struct { Objects []runningOperator `json:"objects"` Status string `json:"status"` Error *Error `json:"error,omitempty"` } if r.Method == "GET" { writeJSON(w, funk.Values(runningOperators.ops)) } }}, }}
var RunnerService = &Service{map[string]*Endpoint{ "/": {Handle: func(w http.ResponseWriter, r *http.Request) { hub := GetHub(r) st := GetStorage(r) if r.Method == "POST" { var data RunState var ri RunInstruction decoder := json.NewDecoder(r.Body) err := decoder.Decode(&ri) if err != nil { data = RunState{Status: "error", Error: &Error{Msg: err.Error(), Code: "E000X"}} writeJSON(w, &data) return } opId := ri.Id op, err := api.BuildAndCompile(opId, ri.Gens, ri.Props, st) if err != nil { data = RunState{Status: "error", Error: &Error{Msg: err.Error(), Code: "E000X"}} writeJSON(w, &data) return } runOp := runningOperators.Run(op) go func() { loop: for { select { case outgoing := <-runOp.outgoing: hub.broadCastTo(Root, Port, outgoing) case <-runOp.outStop: break loop } } }() data.Status = "success" data.Handle = runOp.Handle data.URL = runOp.URL writeJSON(w, &data) } else if r.Method == "DELETE" { type stopInstructionJSON struct { Handle string `json:"handle"` } type outJSON struct { Status string `json:"status"` Error *Error `json:"error,omitempty"` } var data outJSON decoder := json.NewDecoder(r.Body) var si stopInstructionJSON err := decoder.Decode(&si) if err != nil { data = outJSON{Status: "error", Error: &Error{Msg: err.Error(), Code: "E000X"}} writeJSON(w, &data) return } if err := runningOperators.Halt(si.Handle); err == nil { data.Status = "success" } else { data = outJSON{Status: "error", Error: &Error{Msg: "Unknown handle", Code: "E000X"}} } writeJSON(w, &data) } }}, }}
var RunningInstanceService = &Service{map[string]*Endpoint{ "/{handle:\\w+}/": {func(w http.ResponseWriter, r *http.Request) { handle := mux.Vars(r)["handle"] runningIns, err := runningOperators.Get(handle) if err != nil { w.WriteHeader(404) return } var idat interface{} if r.Method == "POST" { r.ParseForm() buf := new(bytes.Buffer) buf.ReadFrom(r.Body) if buf.Len() > 0 { err := json.Unmarshal(buf.Bytes(), &idat) if err != nil { w.WriteHeader(400) return } } runningIns.incoming <- idat writeJSON(w, &runningIns) } }}, }}
var SharingService = &Service{map[string]*Endpoint{ "/export": {func(w http.ResponseWriter, r *http.Request) { fail := func(err *Error) { sendFailure(w, &responseBad{err}) } if r.Method == "GET" { opId, err := uuid.Parse(r.FormValue("id")) if err != nil { fail(&Error{Msg: err.Error(), Code: "E000X"}) return } buf := new(bytes.Buffer) zipWriter := zip.NewWriter(buf) fileWriter, _ := zipWriter.Create("manifest.yaml") manifestBytes, _ := yaml.Marshal(&manifest{ SlangVersion: SlangVersion, TimeUnix: time.Now().Unix(), }) fileWriter.Write(manifestBytes) zipWriter.Close() w.Header().Set("Pragma", "public") w.Header().Set("Expires", "0") w.Header().Set("Cache-Control", "must-revalidate, post-check=0, pre-check=0") w.Header().Set("Cache-Control", "public") w.Header().Set("Content-Description", "File Transfer") w.Header().Set("Content-Type", "application/octet-stream") w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s.zip\"", opId)) w.Header().Set("Content-Transfer-Encoding", "binary") w.Header().Set("Content-Length", fmt.Sprintf("%d", len(buf.Bytes()))) w.Write(buf.Bytes()) } }}, "/import": {func(w http.ResponseWriter, r *http.Request) { fail := func(err *Error) { sendFailure(w, &responseBad{err}) } if r.Method == "POST" { var buf bytes.Buffer file, header, err := r.FormFile("file") if err != nil { fail(&Error{Msg: err.Error(), Code: "E000X"}) return } defer file.Close() io.Copy(&buf, file) zipReader, err := zip.NewReader(file, header.Size) if err != nil { fail(&Error{Msg: err.Error(), Code: "E000X"}) return } manifest := manifest{} for _, file := range zipReader.File { if file.Name == "manifest.yaml" { fileReader, _ := file.Open() buf := new(bytes.Buffer) buf.ReadFrom(fileReader) yaml.Unmarshal(buf.Bytes(), &manifest) fileReader.Close() } } myVersion, err := version.NewVersion(SlangVersion) if err == nil { manifestVersion, err := version.NewVersion(manifest.SlangVersion) if err == nil { if myVersion.LessThan(manifestVersion) { fail(&Error{Msg: "Please upgrade your slang version", Code: "E000X"}) return } } } fail(&Error{Msg: "not implemented yet", Code: "E000X"}) return } }}, }}
Functions ¶
func IsDirEmpty ¶
func IsNewestSlangVersion ¶ added in v0.1.5
Types ¶
type AuthHandleFunc ¶ added in v0.1.27
type AuthHandleFunc func(w http.ResponseWriter, r *http.Request)
type ConnectedClient ¶ added in v0.1.17
type ConnectedClient struct {
// contains filtered or unexported fields
}
ConnectedClient holds everything we need to know about a connection that was made with a websocket
type Hub ¶ added in v0.1.17
type Hub struct {
// contains filtered or unexported fields
}
Hub maintains the set of active clients and broadcasts messages to the clients.
type RunInstruction ¶ added in v0.1.17
type Server ¶
func (*Server) AddRedirect ¶
func (*Server) AddService ¶
func (*Server) AddStaticServer ¶
func (*Server) AddWebsocket ¶ added in v0.1.17
type SlangComponentLoader ¶
type SlangComponentLoader struct {
// contains filtered or unexported fields
}
func NewComponentLoaderLatestMaster ¶
func NewComponentLoaderLatestMaster(repo string, path string) *SlangComponentLoader
func NewComponentLoaderLatestRelease ¶
func NewComponentLoaderLatestRelease(repo string, path string) *SlangComponentLoader
func (*SlangComponentLoader) GetLatestReleaseVersion ¶
func (dl *SlangComponentLoader) GetLatestReleaseVersion() *version.Version
func (*SlangComponentLoader) GetLocalReleaseVersion ¶
func (dl *SlangComponentLoader) GetLocalReleaseVersion() *version.Version
func (*SlangComponentLoader) Load ¶
func (dl *SlangComponentLoader) Load() error
* Downloads & unpacks latest version of a component.
func (*SlangComponentLoader) NewerVersionExists ¶
func (dl *SlangComponentLoader) NewerVersionExists() bool
type Topic ¶ added in v0.1.17
type Topic int
We want types around the topic as this makes it easier to work with. A Topic in this case is meant for easier distinction of what type of message is being send. Basically we attach type information for the other end of the connected client.
func (Topic) MarshalJSON ¶ added in v0.1.17
This encodes a `Topic` to Json using it's string representation
type UserID ¶ added in v0.1.17
type UserID struct {
// contains filtered or unexported fields
}
UserID represents an Identifier for a user of the system This is also intended to deliver `envelops` to the correct `ConnectedClients` instead of sending a message to all connected clients. Currently we do not have real users. The variable acts more as a placeholder and thinking vehicle to remind oneself that the system might have more than one user in the future - I know, YAGNI.