@@ -18,13 +18,21 @@ package filter
1818
1919import (
2020 "context"
21+ "encoding/json"
22+ "errors"
23+ "fmt"
2124
2225 "sigs.k8s.io/controller-runtime/pkg/log"
26+ "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/plugins"
2327 "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/framework"
2428 "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/types"
2529 logutil "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/util/logging"
2630)
2731
32+ const (
33+ DecisionTreeFilterType = "decision-tree"
34+ )
35+
2836// compile-time type assertion
2937var _ framework.Filter = & DecisionTreeFilter {}
3038
@@ -47,6 +55,82 @@ type DecisionTreeFilter struct {
4755 NextOnSuccessOrFailure framework.Filter
4856}
4957
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+
50134// Type returns the type of the filter.
51135func (f * DecisionTreeFilter ) Type () string {
52136 if f == nil {
0 commit comments