Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

Commit

Permalink
Controller: Get Detector based on Id and Name
Browse files Browse the repository at this point in the history
GetDetector will call gateway to get configuration
GetDetectorByName will first call SearchDetector to get ID from Name pattern.
Later, it will call GetDetector to get details.
  • Loading branch information
VijayanB committed Aug 12, 2020
1 parent 153fe52 commit 9243f3c
Show file tree
Hide file tree
Showing 4 changed files with 203 additions and 0 deletions.
50 changes: 50 additions & 0 deletions cli/internal/controller/ad/ad.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,14 @@ type Controller interface {
StartDetector(context.Context, string) error
StopDetector(context.Context, string) error
DeleteDetector(context.Context, string, bool, bool) error
GetDetector(context.Context, string) (*entity.DetectorOutput, error)
CreateAnomalyDetector(context.Context, entity.CreateDetectorRequest) (*string, error)
CreateMultiEntityAnomalyDetector(ctx context.Context, request entity.CreateDetectorRequest, interactive bool, display bool) ([]string, error)
SearchDetectorByName(context.Context, string) ([]entity.Detector, error)
StartDetectorByName(context.Context, string, bool) error
StopDetectorByName(context.Context, string, bool) error
DeleteDetectorByName(context.Context, string, bool, bool) error
GetDetectorsByName(context.Context, string, bool) ([]*entity.DetectorOutput, error)
}

type controller struct {
Expand Down Expand Up @@ -160,6 +162,24 @@ func (c controller) DeleteDetector(ctx context.Context, id string, interactive b
}
return nil
}

//GetDetector fetch detector based on DetectorID
func (c controller) GetDetector(ctx context.Context, ID string) (*entity.DetectorOutput, error) {
if len(ID) < 1 {
return nil, fmt.Errorf("detector Id: %s cannot be empty", ID)
}
response, err := c.gateway.GetDetector(ctx, ID)
if err != nil {
return nil, err
}
var data entity.DetectorResponse
err = json.Unmarshal(response, &data)
if err != nil {
return nil, err
}
return mapper.MapToDetectorOutput(data)
}

func processEntityError(err error) error {
var c entity.CreateError
data := fmt.Sprintf("%v", err)
Expand Down Expand Up @@ -467,5 +487,35 @@ func (c controller) DeleteDetectorByName(ctx context.Context, name string, force
}
}
return nil
}

//GetDetectorsByName get detector based on name pattern. It first calls SearchDetectorByName and then
// gets lists of detectorId and call GetDetector to get individual detector configuration
func (c controller) GetDetectorsByName(ctx context.Context, pattern string, display bool) ([]*entity.DetectorOutput, error) {
matchedDetectors, err := c.getDetectorsToProcess(ctx, "fetch", pattern)
if err != nil {
return nil, err
}
if matchedDetectors == nil {
return nil, nil
}
var bar *pb.ProgressBar
if display {
bar = createProgressBar(len(matchedDetectors))
}
var output []*entity.DetectorOutput
for _, detector := range matchedDetectors {
data, err := c.GetDetector(ctx, detector.ID)
if err != nil {
return nil, err
}
output = append(output, data)
if bar != nil {
bar.Increment()
}
}
if bar != nil {
bar.Finish()
}
return output, nil
}
86 changes: 86 additions & 0 deletions cli/internal/controller/ad/ad_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -724,3 +724,89 @@ func TestController_DeleteDetectorByName(t *testing.T) {
assert.NoError(t, err)
})
}

func TestController_GetDetectorByName(t *testing.T) {
detectorOutput := &entity.DetectorOutput{
ID: "detectorID",
Name: "detector",
Description: "Test detector",
TimeField: "timestamp",
Index: []string{"order*"},
Features: []entity.Feature{
{
Name: "total_order",
Enabled: true,
AggregationQuery: []byte(`{"total_order":{"sum":{"field":"value"}}}`),
},
},
Filter: []byte(`{"bool" : {"filter" : [{"exists" : {"field" : "value","boost" : 1.0}}],"adjust_pure_negative" : true,"boost" : 1.0}}`),
Interval: "5m",
Delay: "1m",
LastUpdatedAt: 1589441737319,
SchemaVersion: 0,
}
t.Run("get empty detector", func(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
mockADGateway := adgateway.NewMockGateway(mockCtrl)
mockESController := esmockctrl.NewMockController(mockCtrl)
ctx := context.Background()
ctrl := New(os.Stdin, mockESController, mockADGateway)
_, err := ctrl.GetDetectorsByName(ctx, "", false)
assert.Error(t, err)
})
t.Run("search detector gateway failed", func(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
ctx := context.Background()
mockADGateway := adgateway.NewMockGateway(mockCtrl)
mockADGateway.EXPECT().SearchDetector(ctx, getSearchPayload("detector")).Return(nil, errors.New("gateway failed"))
mockESController := esmockctrl.NewMockController(mockCtrl)
ctrl := New(os.Stdin, mockESController, mockADGateway)
_, err := ctrl.GetDetectorsByName(ctx, "detector", false)
assert.EqualError(t, err, "gateway failed")
})
t.Run("search detector gateway returned empty", func(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
ctx := context.Background()
mockADGateway := adgateway.NewMockGateway(mockCtrl)
mockADGateway.EXPECT().SearchDetector(ctx, getSearchPayload("detector")).Return([]byte(`{}`), nil)
mockESController := esmockctrl.NewMockController(mockCtrl)
ctrl := New(os.Stdin, mockESController, mockADGateway)
actual, err := ctrl.GetDetectorsByName(ctx, "detector", false)
assert.NoError(t, err)
assert.Nil(t, actual)
})
t.Run("get detector gateway failed", func(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
ctx := context.Background()
mockADGateway := adgateway.NewMockGateway(mockCtrl)
mockADGateway.EXPECT().SearchDetector(ctx, getSearchPayload("detector")).Return(
helperLoadBytes(t, "search_response.json"), nil)
mockADGateway.EXPECT().GetDetector(ctx, "detectorID").Return(nil, errors.New("gateway failed"))
var stdin bytes.Buffer
stdin.Write([]byte("yes\n"))
mockESController := esmockctrl.NewMockController(mockCtrl)
ctrl := New(&stdin, mockESController, mockADGateway)
_, err := ctrl.GetDetectorsByName(ctx, "detector", false)
assert.EqualError(t, err, "gateway failed")
})
t.Run("get detector", func(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
ctx := context.Background()
mockADGateway := adgateway.NewMockGateway(mockCtrl)
mockADGateway.EXPECT().SearchDetector(ctx, getSearchPayload("detector")).Return(
helperLoadBytes(t, "search_response.json"), nil)
mockADGateway.EXPECT().GetDetector(ctx, "detectorID").Return(helperLoadBytes(t, "get_response.json"), nil)
mockESController := esmockctrl.NewMockController(mockCtrl)
var stdin bytes.Buffer
stdin.Write([]byte("yes\n"))
ctrl := New(&stdin, mockESController, mockADGateway)
res, err := ctrl.GetDetectorsByName(ctx, "detector", false)
assert.NoError(t, err)
assert.EqualValues(t, *res[0], *detectorOutput)
})
}
30 changes: 30 additions & 0 deletions cli/internal/controller/ad/mocks/mock_ad.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 37 additions & 0 deletions cli/internal/controller/ad/testdata/get_response.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"_id" : "detectorID",
"_version" : 1,
"_primary_term" : 1,
"_seq_no" : 3,
"anomaly_detector" : {
"name" : "detector",
"description" : "Test detector",
"time_field" : "timestamp",
"indices" : [
"order*"
],
"filter_query" : {"bool" : {"filter" : [{"exists" : {"field" : "value","boost" : 1.0}}],"adjust_pure_negative" : true,"boost" : 1.0}},
"detection_interval" : {
"period" : {
"interval" : 5,
"unit" : "Minutes"
}
},
"window_delay" : {
"period" : {
"interval" : 1,
"unit" : "Minutes"
}
},
"schema_version" : 0,
"feature_attributes" : [
{
"feature_id" : "mYccEnIBTXsGi3mvMd8_",
"feature_name" : "total_order",
"feature_enabled" : true,
"aggregation_query" : {"total_order":{"sum":{"field":"value"}}}
}
],
"last_update_time" : 1589441737319
}
}

0 comments on commit 9243f3c

Please sign in to comment.