github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/service/runtime/handler/source.go (about) 1 package handler 2 3 import ( 4 "bytes" 5 "context" 6 "fmt" 7 "io" 8 9 pb "github.com/tickoalcantara12/micro/v3/proto/runtime" 10 "github.com/tickoalcantara12/micro/v3/service/auth" 11 "github.com/tickoalcantara12/micro/v3/service/errors" 12 "github.com/tickoalcantara12/micro/v3/service/store" 13 ) 14 15 const ( 16 sourcePrefix = "source://" 17 blobNamespacePrefix = "micro/runtime" 18 ) 19 20 // Source implements the proto source service interface 21 type Source struct{} 22 23 // Upload source to the server 24 func (s *Source) Upload(ctx context.Context, stream pb.Source_UploadStream) error { 25 // authorize the request 26 acc, ok := auth.AccountFromContext(ctx) 27 if !ok { 28 return errors.Unauthorized("runtime.Source.Upload", "An account is required to upload source") 29 } 30 namespace := acc.Issuer 31 32 // recieve the source from the client 33 buf := bytes.NewBuffer(nil) 34 var srv *pb.Service 35 for { 36 req, err := stream.Recv() 37 if err == io.EOF { 38 break 39 } else if err != nil { 40 return errors.InternalServerError("runtime.Source.Upload", err.Error()) 41 } 42 43 // get the service from the request, this should be sent on the first message 44 if req.Service != nil { 45 srv = req.Service 46 } 47 48 // write the bytes to the buffer 49 if _, err := buf.Write(req.Data); err != nil { 50 return err 51 } 52 } 53 54 // ensure the blob and a service was sent over the stream 55 if buf == nil { 56 return errors.BadRequest("runtime.Source.Upload", "No blob was sent") 57 } 58 if srv == nil { 59 return errors.BadRequest("runtime.Source.Upload", "No service was sent") 60 } 61 62 // write the source to the store 63 key := fmt.Sprintf("source://%v:%v", srv.Name, srv.Version) 64 opt := store.BlobNamespace(namespace) 65 if err := store.DefaultBlobStore.Write(key, buf, opt); err != nil { 66 return fmt.Errorf("Error writing source to blob store: %v", err) 67 } 68 69 // close the stream 70 return stream.SendAndClose(&pb.UploadResponse{Id: key}) 71 }