Skip to content
This repository was archived by the owner on Dec 9, 2024. It is now read-only.

Commit 6bf544e

Browse files
authored
prevent from removing function with subscriptions. Closes #208 (#370)
1 parent 3312967 commit 6bf544e

File tree

5 files changed

+65
-7
lines changed

5 files changed

+65
-7
lines changed

function/errors.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,10 @@ type ErrFunctionError struct {
5757
func (e ErrFunctionError) Error() string {
5858
return fmt.Sprintf("Function call failed because of runtime error. Error: %q", e.Original)
5959
}
60+
61+
// ErrFunctionHasSubscriptionsError occurs when function with subscription is being deleted.
62+
type ErrFunctionHasSubscriptionsError struct{}
63+
64+
func (e ErrFunctionHasSubscriptionsError) Error() string {
65+
return fmt.Sprintf("Function cannot be deleted because it's subscribed to a least one event.")
66+
}

httpapi/httpapi.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ func (h HTTPAPI) deleteFunction(w http.ResponseWriter, r *http.Request, params h
146146
if err != nil {
147147
if _, ok := err.(*function.ErrFunctionNotFound); ok {
148148
w.WriteHeader(http.StatusNotFound)
149+
} else if _, ok := err.(*function.ErrFunctionHasSubscriptionsError); ok {
150+
w.WriteHeader(http.StatusBadRequest)
149151
} else {
150152
w.WriteHeader(http.StatusInternalServerError)
151153
}

httpapi/httpapi_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,23 @@ func TestRegisterFunction_InternalError(t *testing.T) {
202202
assert.Equal(t, `processing error`, httpresp.Errors[0].Message)
203203
}
204204

205+
func TestDeleteFunction_BadRequest(t *testing.T) {
206+
ctrl := gomock.NewController(t)
207+
defer ctrl.Finish()
208+
router, functions, _ := setup(ctrl)
209+
210+
functions.EXPECT().DeleteFunction("default", function.ID("func1")).Return(&function.ErrFunctionHasSubscriptionsError{})
211+
212+
resp := httptest.NewRecorder()
213+
req, _ := http.NewRequest(http.MethodDelete, "/v1/spaces/default/functions/func1", nil)
214+
router.ServeHTTP(resp, req)
215+
216+
httpresp := &httpapi.Response{}
217+
json.Unmarshal(resp.Body.Bytes(), httpresp)
218+
assert.Equal(t, http.StatusBadRequest, resp.Code)
219+
assert.Equal(t, "Function cannot be deleted because it's subscribed to a least one event.", httpresp.Errors[0].Message)
220+
}
221+
205222
func setup(ctrl *gomock.Controller) (
206223
*httprouter.Router,
207224
*mock.MockFunctionService,

libkv/function.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,17 @@ func (service Service) GetFunctions(space string) (function.Functions, error) {
124124

125125
// DeleteFunction deletes function from the registry.
126126
func (service Service) DeleteFunction(space string, id function.ID) error {
127-
err := service.FunctionStore.Delete(FunctionKey{space, id}.String())
127+
subs, err := service.GetSubscriptions(space)
128+
if err != nil {
129+
return err
130+
}
131+
for _, sub := range subs {
132+
if id == sub.FunctionID {
133+
return &function.ErrFunctionHasSubscriptionsError{}
134+
}
135+
}
136+
137+
err = service.FunctionStore.Delete(FunctionKey{space, id}.String())
128138
if err != nil {
129139
return &function.ErrFunctionNotFound{ID: id}
130140
}

libkv/function_test.go

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -239,9 +239,12 @@ func TestDeleteFunction(t *testing.T) {
239239
ctrl := gomock.NewController(t)
240240
defer ctrl.Finish()
241241

242-
db := mock.NewMockStore(ctrl)
243-
db.EXPECT().Delete("default/testid").Return(nil)
244-
service := &Service{FunctionStore: db, Log: zap.NewNop()}
242+
kvs := []*store.KVPair{}
243+
subscriptionsDB := mock.NewMockStore(ctrl)
244+
subscriptionsDB.EXPECT().List("default/", &store.ReadOptions{Consistent: true}).Return(kvs, nil)
245+
functionsDB := mock.NewMockStore(ctrl)
246+
functionsDB.EXPECT().Delete("default/testid").Return(nil)
247+
service := &Service{FunctionStore: functionsDB, SubscriptionStore: subscriptionsDB, Log: zap.NewNop()}
245248

246249
err := service.DeleteFunction("default", function.ID("testid"))
247250

@@ -252,15 +255,34 @@ func TestDeleteFunction_NotFound(t *testing.T) {
252255
ctrl := gomock.NewController(t)
253256
defer ctrl.Finish()
254257

255-
db := mock.NewMockStore(ctrl)
256-
db.EXPECT().Delete("default/testid").Return(errors.New("KV func not found"))
257-
service := &Service{FunctionStore: db, Log: zap.NewNop()}
258+
kvs := []*store.KVPair{}
259+
subscriptionsDB := mock.NewMockStore(ctrl)
260+
subscriptionsDB.EXPECT().List("default/", &store.ReadOptions{Consistent: true}).Return(kvs, nil)
261+
functionsDB := mock.NewMockStore(ctrl)
262+
functionsDB.EXPECT().Delete("default/testid").Return(errors.New("KV func not found"))
263+
service := &Service{FunctionStore: functionsDB, SubscriptionStore: subscriptionsDB, Log: zap.NewNop()}
258264

259265
err := service.DeleteFunction("default", function.ID("testid"))
260266

261267
assert.EqualError(t, err, `Function "testid" not found.`)
262268
}
263269

270+
func TestDeleteFunction_SubscriptionExists(t *testing.T) {
271+
ctrl := gomock.NewController(t)
272+
defer ctrl.Finish()
273+
274+
kvs := []*store.KVPair{
275+
{Value: []byte(`{"subscriptionId":"s1","default":"default","event":"test","functionId":"testid"}`)}}
276+
subscriptionsDB := mock.NewMockStore(ctrl)
277+
subscriptionsDB.EXPECT().List("default/", &store.ReadOptions{Consistent: true}).Return(kvs, nil)
278+
functionsDB := mock.NewMockStore(ctrl)
279+
service := &Service{FunctionStore: functionsDB, SubscriptionStore: subscriptionsDB, Log: zap.NewNop()}
280+
281+
err := service.DeleteFunction("default", function.ID("testid"))
282+
283+
assert.Equal(t, err, &function.ErrFunctionHasSubscriptionsError{})
284+
}
285+
264286
func TestValidateFunction_AWSLambdaMissingRegion(t *testing.T) {
265287
service := &Service{Log: zap.NewNop()}
266288

0 commit comments

Comments
 (0)