github.com/hyperledger-labs/bdls@v2.1.1+incompatible/integration/nwo/buildserver.go (about) 1 /* 2 Copyright IBM Corp All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package nwo 8 9 import ( 10 "context" 11 "fmt" 12 "net" 13 "net/http" 14 "strings" 15 "sync" 16 "time" 17 18 "github.com/hyperledger/fabric/integration/helpers" 19 20 . "github.com/onsi/gomega" 21 "github.com/onsi/gomega/gexec" 22 ) 23 24 type BuildServer struct { 25 server *http.Server 26 lis net.Listener 27 } 28 29 func NewBuildServer(args ...string) *BuildServer { 30 return &BuildServer{ 31 server: &http.Server{ 32 Handler: &buildHandler{args: args}, 33 }, 34 } 35 } 36 37 func (s *BuildServer) Serve() { 38 lis, err := net.Listen("tcp", "127.0.0.1:0") 39 Expect(err).NotTo(HaveOccurred()) 40 41 s.lis = lis 42 go s.server.Serve(lis) 43 } 44 45 func (s *BuildServer) Shutdown() { 46 ctx, cancel := context.WithTimeout(context.Background(), time.Minute) 47 defer cancel() 48 defer gexec.CleanupBuildArtifacts() 49 50 s.server.Shutdown(ctx) 51 } 52 53 func (s *BuildServer) Components() *Components { 54 Expect(s.lis).NotTo(BeNil()) 55 56 helpers.AssertImagesExist(RequiredImages...) 57 58 return &Components{ 59 ServerAddress: s.lis.Addr().String(), 60 } 61 } 62 63 type artifact struct { 64 mutex sync.Mutex 65 input string 66 output string 67 } 68 69 func (a *artifact) build(args ...string) error { 70 a.mutex.Lock() 71 defer a.mutex.Unlock() 72 73 if a.output != "" { 74 return nil 75 } 76 77 output, err := gexec.Build(a.input, args...) 78 if err != nil { 79 return err 80 } 81 82 a.output = output 83 return nil 84 } 85 86 type buildHandler struct { 87 mutex sync.Mutex 88 artifacts map[string]*artifact 89 args []string 90 } 91 92 func (b *buildHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { 93 if req.Method != http.MethodGet { 94 w.WriteHeader(http.StatusBadRequest) 95 return 96 } 97 98 input := strings.TrimPrefix(req.URL.Path, "/") 99 a := b.artifact(input) 100 101 if err := a.build(b.args...); err != nil { 102 w.WriteHeader(http.StatusInternalServerError) 103 fmt.Fprintf(w, "%s", err) 104 return 105 } 106 107 w.WriteHeader(http.StatusOK) 108 fmt.Fprintf(w, "%s", a.output) 109 } 110 111 func (b *buildHandler) artifact(input string) *artifact { 112 b.mutex.Lock() 113 defer b.mutex.Unlock() 114 115 if b.artifacts == nil { 116 b.artifacts = map[string]*artifact{} 117 } 118 119 a, ok := b.artifacts[input] 120 if !ok { 121 a = &artifact{input: input} 122 b.artifacts[input] = a 123 } 124 125 return a 126 }