@@ -18,13 +18,21 @@ package filter
18
18
19
19
import (
20
20
"context"
21
+ "encoding/json"
22
+ "errors"
23
+ "fmt"
21
24
22
25
"sigs.k8s.io/controller-runtime/pkg/log"
26
+ "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/plugins"
23
27
"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/framework"
24
28
"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/types"
25
29
logutil "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/util/logging"
26
30
)
27
31
32
+ const (
33
+ DecisionTreeFilterType = "decision-tree"
34
+ )
35
+
28
36
// compile-time type assertion
29
37
var _ framework.Filter = & DecisionTreeFilter {}
30
38
@@ -47,6 +55,82 @@ type DecisionTreeFilter struct {
47
55
NextOnSuccessOrFailure framework.Filter
48
56
}
49
57
58
+ type decisionTreeFilterParameters struct {
59
+ Current * decisionTreeFilterEntry `json:"current"`
60
+ NextOnSuccess * decisionTreeFilterEntry `json:"nextOnSuccess"`
61
+ NextOnFailure * decisionTreeFilterEntry `json:"nextOnFailure"`
62
+ NextOnSuccessOrFailure * decisionTreeFilterEntry `json:"nextOnSuccessOrFailure"`
63
+ }
64
+
65
+ type decisionTreeFilterEntry struct {
66
+ PluginRef * string `json:"pluginRef"`
67
+ DecisionTree * decisionTreeFilterParameters `json:"decisionTree"`
68
+ }
69
+
70
+ func DecisionTreeFilterFactory (name string , rawParameters json.RawMessage , handle plugins.Handle ) (plugins.Plugin , error ) {
71
+ parameters := decisionTreeFilterParameters {}
72
+ if err := json .Unmarshal (rawParameters , & parameters ); err != nil {
73
+ return nil , fmt .Errorf ("failed to parse the parameters of the '%s' filter - %w" , name , err )
74
+ }
75
+ return loadDecisionTree (& parameters , handle )
76
+ }
77
+
78
+ func loadDecisionTree (parameters * decisionTreeFilterParameters , handle plugins.Handle ) (* DecisionTreeFilter , error ) {
79
+ result := & DecisionTreeFilter {}
80
+ var err error
81
+
82
+ if parameters .Current == nil {
83
+ return nil , errors .New ("a current filter must be specified" )
84
+ }
85
+ result .Current , err = loadDecisionTreeEntry (parameters .Current , handle )
86
+ if err != nil {
87
+ return nil , err
88
+ }
89
+
90
+ if parameters .NextOnSuccess != nil {
91
+ result .NextOnSuccess , err = loadDecisionTreeEntry (parameters .NextOnSuccess , handle )
92
+ if err != nil {
93
+ return nil , err
94
+ }
95
+ }
96
+
97
+ if parameters .NextOnFailure != nil {
98
+ result .NextOnFailure , err = loadDecisionTreeEntry (parameters .NextOnFailure , handle )
99
+ if err != nil {
100
+ return nil , err
101
+ }
102
+ }
103
+
104
+ if parameters .NextOnSuccessOrFailure != nil {
105
+ result .NextOnSuccessOrFailure , err = loadDecisionTreeEntry (parameters .NextOnSuccessOrFailure , handle )
106
+ if err != nil {
107
+ return nil , err
108
+ }
109
+ }
110
+
111
+ return result , nil
112
+ }
113
+
114
+ func loadDecisionTreeEntry (entry * decisionTreeFilterEntry , handle plugins.Handle ) (framework.Filter , error ) {
115
+ if entry .PluginRef != nil && entry .DecisionTree != nil {
116
+ return nil , errors .New ("both pluginRef and decisionTree may not be specified" )
117
+ }
118
+
119
+ if entry .PluginRef != nil {
120
+ instance := handle .Plugins ().Plugin (* entry .PluginRef )
121
+ if instance == nil {
122
+ return nil , errors .New (* entry .PluginRef + " is a reference to an undefined Plugin" )
123
+ }
124
+ if theFilter , ok := instance .(framework.Filter ); ok {
125
+ return theFilter , nil
126
+ }
127
+ return nil , errors .New (* entry .PluginRef + " is not a filter" )
128
+ } else if entry .DecisionTree != nil {
129
+ return loadDecisionTree (entry .DecisionTree , handle )
130
+ }
131
+ return nil , errors .New ("either pluginRef or decisionTree must be specified" )
132
+ }
133
+
50
134
// Type returns the type of the filter.
51
135
func (f * DecisionTreeFilter ) Type () string {
52
136
if f == nil {
0 commit comments