11package volumecommands
22
33import (
4+ "context"
45 "errors"
56 "net/http"
67 "path/filepath"
@@ -99,67 +100,93 @@ func registerVolCreateStepFuncs() {
99100}
100101
101102func volumeCreateHandler (w http.ResponseWriter , r * http.Request ) {
103+ var (
104+ err error
105+ req api.VolCreateReq
106+ ctx = r .Context ()
107+ logger = gdctx .GetReqLogger (ctx )
108+ )
102109
103- ctx := r .Context ()
104- ctx , span := trace .StartSpan (ctx , "/volumeCreateHandler" )
105- defer span .End ()
106-
107- logger := gdctx .GetReqLogger (ctx )
108- var err error
109-
110- var req api.VolCreateReq
111110 if err := restutils .UnmarshalRequest (r , & req ); err != nil {
112111 restutils .SendHTTPError (ctx , w , http .StatusBadRequest , gderrors .ErrJSONParsingFailed )
113112 return
114113 }
115114
116- if err := validateVolCreateReq (& req ); err != nil {
117- restutils .SendHTTPError (ctx , w , http .StatusBadRequest , err )
115+ if status , err := CreateVolume (ctx , req ); err != nil {
116+ restutils .SendHTTPError (ctx , w , status , err )
117+ return
118+ }
119+
120+ volinfo , err := volume .GetVolume (req .Name )
121+ if err != nil {
122+ // FIXME: If volume was created successfully in the txn above and
123+ // then the store goes down by the time we reach here, what do
124+ // we return to the client ?
125+ restutils .SendHTTPError (ctx , w , http .StatusInternalServerError , err )
118126 return
119127 }
120128
129+ logger .WithField ("volume-name" , volinfo .Name ).Info ("new volume created" )
130+ events .Broadcast (volume .NewEvent (volume .EventVolumeCreated , volinfo ))
131+
132+ resp := createVolumeCreateResp (volinfo )
133+ restutils .SetLocationHeader (r , w , volinfo .Name )
134+ restutils .SendHTTPResponse (ctx , w , http .StatusCreated , resp )
135+ }
136+
137+ func createVolumeCreateResp (v * volume.Volinfo ) * api.VolumeCreateResp {
138+ return (* api .VolumeCreateResp )(volume .CreateVolumeInfoResp (v ))
139+ }
140+
141+ // CreateVolume will create a volume. It returns http StatusCode to be sent to client
142+ // and any error if occurred.
143+ func CreateVolume (ctx context.Context , req api.VolCreateReq ) (status int , err error ) {
144+ ctx , span := trace .StartSpan (ctx , "/volumeCreateHandler" )
145+ defer span .End ()
146+
147+ if err := validateVolCreateReq (& req ); err != nil {
148+ return http .StatusBadRequest , err
149+ }
150+
121151 if req .Size > 0 {
122152 applyDefaults (& req )
123153
124154 if req .SnapshotReserveFactor < 1 {
125- restutils .SendHTTPError (ctx , w , http .StatusBadRequest ,
126- errors .New ("invalid snapshot reserve factor" ))
127- return
155+ return http .StatusBadRequest , errors .New ("invalid snapshot reserve factor" )
156+
128157 }
129158
130159 if err := bricksplanner .PlanBricks (& req ); err != nil {
131- restutils . SendHTTPError ( ctx , w , http .StatusInternalServerError , err )
132- return
160+ return http .StatusInternalServerError , err
161+
133162 }
134163 } else {
135164 if err := checkDupBrickEntryVolCreate (req ); err != nil {
136- restutils . SendHTTPError ( ctx , w , http .StatusBadRequest , err )
137- return
165+ return http .StatusBadRequest , err
166+
138167 }
139168 }
140169
141170 req .Options , err = expandGroupOptions (req .Options )
142171 if err != nil {
143- restutils . SendHTTPError ( ctx , w , http .StatusInternalServerError , err )
144- return
172+ return http .StatusInternalServerError , err
173+
145174 }
146175
147176 if err := validateOptions (req .Options , req .VolOptionFlags ); err != nil {
148- restutils . SendHTTPError ( ctx , w , http .StatusBadRequest , err )
149- return
177+ return http .StatusBadRequest , err
178+
150179 }
151180
152181 nodes , err := req .Nodes ()
153182 if err != nil {
154- restutils . SendHTTPError ( ctx , w , http .StatusBadRequest , err )
155- return
183+ return http .StatusBadRequest , err
184+
156185 }
157186
158187 txn , err := transaction .NewTxnWithLocks (ctx , req .Name )
159188 if err != nil {
160- status , err := restutils .ErrToStatusCode (err )
161- restutils .SendHTTPError (ctx , w , status , err )
162- return
189+ return restutils .ErrToStatusCode (err )
163190 }
164191 defer txn .Done ()
165192
@@ -191,8 +218,8 @@ func volumeCreateHandler(w http.ResponseWriter, r *http.Request) {
191218 }
192219
193220 if err := txn .Ctx .Set ("req" , & req ); err != nil {
194- restutils . SendHTTPError ( ctx , w , http .StatusInternalServerError , err )
195- return
221+ return http .StatusInternalServerError , err
222+
196223 }
197224
198225 // Add attributes to the span with info that can be viewed along with traces.
@@ -203,28 +230,8 @@ func volumeCreateHandler(w http.ResponseWriter, r *http.Request) {
203230 )
204231
205232 if err := txn .Do (); err != nil {
206- status , err := restutils .ErrToStatusCode (err )
207- restutils .SendHTTPError (ctx , w , status , err )
208- return
233+ return restutils .ErrToStatusCode (err )
209234 }
210235
211- volinfo , err := volume .GetVolume (req .Name )
212- if err != nil {
213- // FIXME: If volume was created successfully in the txn above and
214- // then the store goes down by the time we reach here, what do
215- // we return to the client ?
216- restutils .SendHTTPError (ctx , w , http .StatusInternalServerError , err )
217- return
218- }
219-
220- logger .WithField ("volume-name" , volinfo .Name ).Info ("new volume created" )
221- events .Broadcast (volume .NewEvent (volume .EventVolumeCreated , volinfo ))
222-
223- resp := createVolumeCreateResp (volinfo )
224- restutils .SetLocationHeader (r , w , volinfo .Name )
225- restutils .SendHTTPResponse (ctx , w , http .StatusCreated , resp )
226- }
227-
228- func createVolumeCreateResp (v * volume.Volinfo ) * api.VolumeCreateResp {
229- return (* api .VolumeCreateResp )(volume .CreateVolumeInfoResp (v ))
236+ return http .StatusCreated , nil
230237}
0 commit comments