Skip to content

Commit 35a61ce

Browse files
committed
Revert "Temporarily remove the package binding_request to do that in a separate PR;"
This reverts commit 36934ab.
1 parent 36934ab commit 35a61ce

File tree

13 files changed

+1543
-0
lines changed

13 files changed

+1543
-0
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../../../schema/json/autoscaler-policy.json
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../../../schema/json/binding-configuration.json
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package binding_request
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/xeipuuv/gojsonschema"
7+
8+
"code.cloudfoundry.org/app-autoscaler/src/autoscaler/models"
9+
)
10+
11+
type Parameters struct {
12+
// 🚧 To-do: We should distinguish between raw data and correctly validated data.
13+
Configuration *models.BindingConfig
14+
15+
// 🚧 To-do: We should distinguish between raw data and correctly validated data.
16+
ScalingPolicy *models.ScalingPolicy
17+
}
18+
19+
type JsonSchemaError []gojsonschema.ResultError
20+
21+
func (e JsonSchemaError) Error() string {
22+
var errors []gojsonschema.ResultError = e
23+
return fmt.Sprintf("%s", errors)
24+
}
25+
26+
type Parser interface {
27+
// Default policies are specified on service-instance-level. Consequently, we need to leave the
28+
// field Parameters.ScalingPolicy empty when no policy has been specified and instead … let the
29+
// consumer of the BindingRequest decided what to do with this (i.e. he will use then the
30+
// default-policy.)
31+
Parse(bindingReqParams string) (Parameters, error)
32+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package binding_request_test
2+
3+
import (
4+
. "github.com/onsi/ginkgo/v2"
5+
. "github.com/onsi/gomega"
6+
7+
"testing"
8+
)
9+
10+
func TestServer(t *testing.T) {
11+
RegisterFailHandler(Fail)
12+
RunSpecs(t, "BindingRequestParser test suite")
13+
}
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
package binding_request_test
2+
3+
import (
4+
. "github.com/onsi/ginkgo/v2"
5+
. "github.com/onsi/gomega"
6+
7+
br "code.cloudfoundry.org/app-autoscaler/src/autoscaler/api/binding_request"
8+
clp "code.cloudfoundry.org/app-autoscaler/src/autoscaler/api/binding_request/clean_parser"
9+
cp "code.cloudfoundry.org/app-autoscaler/src/autoscaler/api/binding_request/combined_parser"
10+
lp "code.cloudfoundry.org/app-autoscaler/src/autoscaler/api/binding_request/legacy_parser"
11+
"code.cloudfoundry.org/app-autoscaler/src/autoscaler/models"
12+
)
13+
14+
var _ = Describe("BindingRequestParsers", func() {
15+
const cleanSchemaFilePath string = "file://./binding-request.json"
16+
const validModernBindingRequestRaw string = `
17+
{
18+
"configuration": {
19+
"app_guid": "8d0cee08-23ad-4813-a779-ad8118ea0b91",
20+
"custom_metrics": {
21+
"metric_submission_strategy": {
22+
"allow_from": "bound_app"
23+
}
24+
}
25+
},
26+
"scaling-policy": {
27+
"instance_min_count": 1,
28+
"instance_max_count": 4,
29+
"scaling_rules": [
30+
{
31+
"metric_type": "memoryutil",
32+
"breach_duration_secs": 600,
33+
"threshold": 30,
34+
"operator": "<",
35+
"cool_down_secs": 300,
36+
"adjustment": "-1"
37+
},
38+
{
39+
"metric_type": "memoryutil",
40+
"breach_duration_secs": 600,
41+
"threshold": 90,
42+
"operator": ">=",
43+
"cool_down_secs": 300,
44+
"adjustment": "+1"
45+
}
46+
]
47+
}
48+
}`
49+
const validLegacyBindingRequestRaw string = `
50+
{
51+
"configuration": {
52+
"app_guid": "8d0cee08-23ad-4813-a779-ad8118ea0b91",
53+
"custom_metrics": {
54+
"metric_submission_strategy": {
55+
"allow_from": "bound_app"
56+
}
57+
}
58+
},
59+
"instance_min_count": 1,
60+
"instance_max_count": 4,
61+
"scaling_rules": [
62+
{
63+
"metric_type": "memoryutil",
64+
"breach_duration_secs": 600,
65+
"threshold": 30,
66+
"operator": "<",
67+
"cool_down_secs": 300,
68+
"adjustment": "-1"
69+
},
70+
{
71+
"metric_type": "memoryutil",
72+
"breach_duration_secs": 600,
73+
"threshold": 90,
74+
"operator": ">=",
75+
"cool_down_secs": 300,
76+
"adjustment": "+1"
77+
}
78+
]
79+
}`
80+
81+
Describe("CleanBindingRequestParser", func() {
82+
var (
83+
cleanParser clp.CleanBindingRequestParser
84+
err error
85+
)
86+
var _ = BeforeEach(func() {
87+
cleanParser, err = clp.NewFromFile(cleanSchemaFilePath)
88+
Expect(err).NotTo(HaveOccurred())
89+
})
90+
Context("When using the new format for binding-requests", func() {
91+
Context("and parsing a valid and complete one", func() {
92+
It("should return a correctly populated BindingRequestParameters", func() {
93+
bindingRequestRaw := validModernBindingRequestRaw
94+
95+
bindingRequest, err := cleanParser.Parse(bindingRequestRaw)
96+
97+
Expect(err).NotTo(HaveOccurred())
98+
Expect(bindingRequest.Configuration.AppGUID).To(
99+
Equal(models.GUID("8d0cee08-23ad-4813-a779-ad8118ea0b91")))
100+
})
101+
})
102+
})
103+
})
104+
105+
Describe("LegacyBindingRequestParser", func() {
106+
var (
107+
legacyParser lp.LegacyBindingRequestParser
108+
err error
109+
)
110+
var _ = BeforeEach(func() {
111+
legacyParser, err = lp.New()
112+
Expect(err).NotTo(HaveOccurred())
113+
})
114+
115+
Context("When using the legacy format for binding-requests", func() {
116+
It("should return a correctly populated BindingRequestParameters", func() {
117+
bindingRequestRaw := validLegacyBindingRequestRaw
118+
119+
bindingRequest, err := legacyParser.Parse(bindingRequestRaw)
120+
121+
Expect(err).NotTo(HaveOccurred())
122+
Expect(bindingRequest.Configuration.AppGUID).
123+
To(Equal(models.GUID("8d0cee08-23ad-4813-a779-ad8118ea0b91")))
124+
// 🚧 To-do: Add a few more field-comparisons;
125+
})
126+
})
127+
})
128+
129+
Describe("CombinedBindingRequestParser", func() {
130+
var (
131+
cleanParser clp.CleanBindingRequestParser
132+
legacyParser lp.LegacyBindingRequestParser
133+
combinedParser cp.CombinedBindingRequestParser
134+
135+
err error
136+
)
137+
var _ = BeforeEach(func() {
138+
cleanParser, err = clp.NewFromFile(cleanSchemaFilePath)
139+
Expect(err).NotTo(HaveOccurred())
140+
legacyParser, err = lp.New()
141+
Expect(err).NotTo(HaveOccurred())
142+
combinedParser = cp.New([]br.Parser{cleanParser, legacyParser})
143+
})
144+
145+
Context("When using the new format for binding-requests", func() {
146+
Context("and parsing a valid and complete one", func() {
147+
It("should return a correctly populated BindingRequestParameters", func() {
148+
bindingRequestRaw := validModernBindingRequestRaw
149+
150+
bindingRequest, err := combinedParser.Parse(bindingRequestRaw)
151+
152+
Expect(err).NotTo(HaveOccurred())
153+
Expect(bindingRequest.Configuration.AppGUID).To(
154+
Equal(models.GUID("8d0cee08-23ad-4813-a779-ad8118ea0b91")))
155+
})
156+
})
157+
})
158+
159+
Context("When using the legacy format for binding-requests", func() {
160+
It("should return a correctly populated BindingRequestParameters", func() {
161+
bindingRequestRaw := validLegacyBindingRequestRaw
162+
163+
bindingRequest, err := combinedParser.Parse(bindingRequestRaw)
164+
165+
Expect(err).NotTo(HaveOccurred())
166+
Expect(bindingRequest.Configuration.AppGUID).
167+
To(Equal(models.GUID("8d0cee08-23ad-4813-a779-ad8118ea0b91")))
168+
// 🚧 To-do: Add a few more field-comparisons;
169+
})
170+
})
171+
})
172+
})
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../../../schema/json/binding-request.json
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package clean_parser
2+
3+
type parameters struct {
4+
Configuration *bindingCfg `json:"configuration"`
5+
ScalingPolicy *scalingPolicy `json:"scaling-policy"`
6+
}
7+
8+
// ================================================================================
9+
// Binding-configuration
10+
// ================================================================================
11+
12+
type bindingCfg struct {
13+
CustomMetricsCfg customMetricsCfg
14+
AppGuid string `json:"app_guid"`
15+
}
16+
17+
type customMetricsCfg struct {
18+
MetricSubmStrat metricSubmStrat `json:"metric_submission_strategy"`
19+
}
20+
21+
type metricSubmStrat struct {
22+
AllowFrom string `json:"allow_from"`
23+
}
24+
25+
// ================================================================================
26+
// Scaling-policy
27+
// ================================================================================
28+
29+
type scalingPolicy struct {
30+
SchemaVersion string `json:"schema-version"`
31+
InstanceMinCount int `json:"instance_min_count"`
32+
InstanceMaxCount int `json:"instance_max_count"`
33+
ScalingRules []scalingRule `json:"scaling_rules,omitempty"`
34+
Schedules *scalingSchedule `json:"schedules,omitempty"`
35+
}
36+
37+
type scalingRule struct {
38+
MetricType string `json:"metric_type"`
39+
BreachDurationSecs int `json:"breach_duration_secs,omitempty"`
40+
Threshold int64 `json:"threshold"`
41+
Operator string `json:"operator"`
42+
CoolDownSecs int `json:"cool_down_secs,omitempty"`
43+
Adjustment string `json:"adjustment"`
44+
}
45+
46+
type scalingSchedule struct {
47+
Timezone string `json:"timezone"`
48+
RecurringSchedule []recurringSchedule `json:"recurring_schedule,omitempty"`
49+
SpecificDate []specificDate `json:"specific_date,omitempty"`
50+
}
51+
52+
type recurringSchedule struct {
53+
StartTime string `json:"start_time"`
54+
EndTime string `json:"end_time"`
55+
DaysOfWeek []int `json:"days_of_week,omitempty"`
56+
DaysOfMonth []int `json:"days_of_month,omitempty"`
57+
InstanceMinCount int `json:"instance_min_count"`
58+
InstanceMaxCount int `json:"instance_max_count"`
59+
InitialMinInstanceCount int `json:"initial_min_instance_count,omitempty"`
60+
StartDate string `json:"start_date,omitempty"`
61+
EndDate string `json:"end_date,omitempty"`
62+
}
63+
64+
type specificDate struct {
65+
StartDateTime string `json:"start_date_time"`
66+
EndDateTime string `json:"end_date_time"`
67+
InstanceMinCount int `json:"instance_min_count"`
68+
InstanceMaxCount int `json:"instance_max_count"`
69+
InitialMinInstanceCount int `json:"initial_min_instance_count,omitempty"`
70+
}

0 commit comments

Comments
 (0)