fix(protocol): fence gateway work recovery
This commit is contained in:
+71
-27
@@ -14,7 +14,7 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
const SchemaSHA256 = "614fa11dd1f49b8e10bf21b8c10eadbc1468d16bfcc6ed0a26d29671a5e61300"
|
||||
const SchemaSHA256 = "8c1ed430127cf5774a919f14ff4770b2509d322c8518bf30c412e1e89eeffced"
|
||||
const ProtocolVersion = "1.0.0"
|
||||
const CurrentWireVersion = "2"
|
||||
const NMinus1WireVersion = "1"
|
||||
@@ -330,8 +330,9 @@ type GatewayQualityAck struct {
|
||||
ReconnectSequence int64 `json:"reconnect_sequence"`
|
||||
OperationID string `json:"operation_id"`
|
||||
Revision int64 `json:"revision"`
|
||||
LeaseGeneration int64 `json:"lease_generation"`
|
||||
Outcome string `json:"outcome"`
|
||||
CurrentAppliedRevision int64 `json:"current_applied_revision"`
|
||||
CurrentAppliedRevision *int64 `json:"current_applied_revision,omitempty"`
|
||||
FailureCode string `json:"failure_code,omitempty"`
|
||||
}
|
||||
|
||||
@@ -342,6 +343,7 @@ type GatewayQualityWork struct {
|
||||
ReconnectSequence int64 `json:"reconnect_sequence"`
|
||||
OperationID string `json:"operation_id"`
|
||||
Revision int64 `json:"revision"`
|
||||
LeaseGeneration int64 `json:"lease_generation"`
|
||||
LeaseExpiresAt string `json:"lease_expires_at"`
|
||||
SelectedDescriptor SelectedSessionDescriptor `json:"selected_descriptor"`
|
||||
CurrentAppliedRevision *int64 `json:"current_applied_revision,omitempty"`
|
||||
@@ -352,8 +354,10 @@ type GatewayQualityWorkRequest struct {
|
||||
SessionID string `json:"session_id"`
|
||||
GatewayID string `json:"gateway_id"`
|
||||
ReconnectSequence int64 `json:"reconnect_sequence"`
|
||||
OperationID string `json:"operation_id"`
|
||||
Revision int64 `json:"revision"`
|
||||
Acquisition string `json:"acquisition"`
|
||||
OperationID string `json:"operation_id,omitempty"`
|
||||
Revision *int64 `json:"revision,omitempty"`
|
||||
LeaseGeneration *int64 `json:"lease_generation,omitempty"`
|
||||
CurrentAppliedRevision *int64 `json:"current_applied_revision,omitempty"`
|
||||
}
|
||||
|
||||
@@ -397,7 +401,8 @@ type GatewayStopWorkRequest struct {
|
||||
SessionID string `json:"session_id"`
|
||||
GatewayID string `json:"gateway_id"`
|
||||
ReconnectSequence int64 `json:"reconnect_sequence"`
|
||||
OperationID string `json:"operation_id"`
|
||||
Acquisition string `json:"acquisition"`
|
||||
OperationID string `json:"operation_id,omitempty"`
|
||||
}
|
||||
|
||||
type GatewayTelemetry struct {
|
||||
@@ -3487,13 +3492,19 @@ func (v GatewayQualityAck) Validate() error {
|
||||
if v.Revision != 0 && v.Revision < 1 {
|
||||
violations = append(violations, FieldViolation{Field: "revision", Code: "minimum"})
|
||||
}
|
||||
if v.LeaseGeneration == 0 {
|
||||
violations = append(violations, FieldViolation{Field: "lease_generation", Code: "required"})
|
||||
}
|
||||
if v.LeaseGeneration != 0 && v.LeaseGeneration < 1 {
|
||||
violations = append(violations, FieldViolation{Field: "lease_generation", Code: "minimum"})
|
||||
}
|
||||
if v.Outcome == "" {
|
||||
violations = append(violations, FieldViolation{Field: "outcome", Code: "required"})
|
||||
}
|
||||
if v.Outcome != "" && !(v.Outcome == "applied" || v.Outcome == "not_applied" || v.Outcome == "uncertain") {
|
||||
if v.Outcome != "" && !(v.Outcome == "applied" || v.Outcome == "proven_prior" || v.Outcome == "unknown") {
|
||||
violations = append(violations, FieldViolation{Field: "outcome", Code: "invalid_value"})
|
||||
}
|
||||
if v.CurrentAppliedRevision != 0 && v.CurrentAppliedRevision < 0 {
|
||||
if v.CurrentAppliedRevision != nil && *v.CurrentAppliedRevision != 0 && *v.CurrentAppliedRevision < 0 {
|
||||
violations = append(violations, FieldViolation{Field: "current_applied_revision", Code: "minimum"})
|
||||
}
|
||||
if len(v.FailureCode) < 1 && v.FailureCode != "" {
|
||||
@@ -3502,6 +3513,15 @@ func (v GatewayQualityAck) Validate() error {
|
||||
if len(v.FailureCode) > 128 {
|
||||
violations = append(violations, FieldViolation{Field: "failure_code", Code: "max_length"})
|
||||
}
|
||||
if v.Outcome == "applied" && (v.CurrentAppliedRevision == nil || *v.CurrentAppliedRevision != v.Revision) {
|
||||
violations = append(violations, FieldViolation{Field: "current_applied_revision", Code: "invalid_tagged_value"})
|
||||
}
|
||||
if v.Outcome == "proven_prior" && (v.CurrentAppliedRevision == nil || *v.CurrentAppliedRevision >= v.Revision) {
|
||||
violations = append(violations, FieldViolation{Field: "current_applied_revision", Code: "invalid_tagged_value"})
|
||||
}
|
||||
if v.Outcome == "unknown" && v.CurrentAppliedRevision != nil {
|
||||
violations = append(violations, FieldViolation{Field: "current_applied_revision", Code: "invalid_tagged_value"})
|
||||
}
|
||||
if len(violations) > 0 {
|
||||
return ValidationError{Violations: violations}
|
||||
}
|
||||
@@ -3520,12 +3540,12 @@ func DecodeGatewayQualityAck(data []byte) (GatewayQualityAck, error) {
|
||||
if err := json.Unmarshal(data, &fields); err != nil {
|
||||
return value, err
|
||||
}
|
||||
if raw, ok := fields["current_applied_revision"]; !ok || bytes.Equal(bytes.TrimSpace(raw), []byte("null")) {
|
||||
return value, ValidationError{Violations: []FieldViolation{{Field: "current_applied_revision", Code: "required"}}}
|
||||
}
|
||||
if raw, ok := fields["gateway_id"]; !ok || bytes.Equal(bytes.TrimSpace(raw), []byte("null")) {
|
||||
return value, ValidationError{Violations: []FieldViolation{{Field: "gateway_id", Code: "required"}}}
|
||||
}
|
||||
if raw, ok := fields["lease_generation"]; !ok || bytes.Equal(bytes.TrimSpace(raw), []byte("null")) {
|
||||
return value, ValidationError{Violations: []FieldViolation{{Field: "lease_generation", Code: "required"}}}
|
||||
}
|
||||
if raw, ok := fields["operation_id"]; !ok || bytes.Equal(bytes.TrimSpace(raw), []byte("null")) {
|
||||
return value, ValidationError{Violations: []FieldViolation{{Field: "operation_id", Code: "required"}}}
|
||||
}
|
||||
@@ -3616,6 +3636,12 @@ func (v GatewayQualityWork) Validate() error {
|
||||
if v.Revision != 0 && v.Revision < 1 {
|
||||
violations = append(violations, FieldViolation{Field: "revision", Code: "minimum"})
|
||||
}
|
||||
if v.LeaseGeneration == 0 {
|
||||
violations = append(violations, FieldViolation{Field: "lease_generation", Code: "required"})
|
||||
}
|
||||
if v.LeaseGeneration != 0 && v.LeaseGeneration < 1 {
|
||||
violations = append(violations, FieldViolation{Field: "lease_generation", Code: "minimum"})
|
||||
}
|
||||
if v.LeaseExpiresAt == "" {
|
||||
violations = append(violations, FieldViolation{Field: "lease_expires_at", Code: "required"})
|
||||
}
|
||||
@@ -3660,6 +3686,9 @@ func DecodeGatewayQualityWork(data []byte) (GatewayQualityWork, error) {
|
||||
if raw, ok := fields["lease_expires_at"]; !ok || bytes.Equal(bytes.TrimSpace(raw), []byte("null")) {
|
||||
return value, ValidationError{Violations: []FieldViolation{{Field: "lease_expires_at", Code: "required"}}}
|
||||
}
|
||||
if raw, ok := fields["lease_generation"]; !ok || bytes.Equal(bytes.TrimSpace(raw), []byte("null")) {
|
||||
return value, ValidationError{Violations: []FieldViolation{{Field: "lease_generation", Code: "required"}}}
|
||||
}
|
||||
if raw, ok := fields["operation_id"]; !ok || bytes.Equal(bytes.TrimSpace(raw), []byte("null")) {
|
||||
return value, ValidationError{Violations: []FieldViolation{{Field: "operation_id", Code: "required"}}}
|
||||
}
|
||||
@@ -3732,8 +3761,11 @@ func (v GatewayQualityWorkRequest) Validate() error {
|
||||
if v.ReconnectSequence != 0 && v.ReconnectSequence < 0 {
|
||||
violations = append(violations, FieldViolation{Field: "reconnect_sequence", Code: "minimum"})
|
||||
}
|
||||
if v.OperationID == "" {
|
||||
violations = append(violations, FieldViolation{Field: "operation_id", Code: "required"})
|
||||
if v.Acquisition == "" {
|
||||
violations = append(violations, FieldViolation{Field: "acquisition", Code: "required"})
|
||||
}
|
||||
if v.Acquisition != "" && !(v.Acquisition == "poll" || v.Acquisition == "prompt" || v.Acquisition == "observation") {
|
||||
violations = append(violations, FieldViolation{Field: "acquisition", Code: "invalid_value"})
|
||||
}
|
||||
if len(v.OperationID) < 36 && v.OperationID != "" {
|
||||
violations = append(violations, FieldViolation{Field: "operation_id", Code: "min_length"})
|
||||
@@ -3744,15 +3776,24 @@ func (v GatewayQualityWorkRequest) Validate() error {
|
||||
if v.OperationID != "" && !validCanonicalUUID(v.OperationID) {
|
||||
violations = append(violations, FieldViolation{Field: "operation_id", Code: "invalid_uuid"})
|
||||
}
|
||||
if v.Revision == 0 {
|
||||
violations = append(violations, FieldViolation{Field: "revision", Code: "required"})
|
||||
}
|
||||
if v.Revision != 0 && v.Revision < 1 {
|
||||
if v.Revision != nil && *v.Revision != 0 && *v.Revision < 1 {
|
||||
violations = append(violations, FieldViolation{Field: "revision", Code: "minimum"})
|
||||
}
|
||||
if v.LeaseGeneration != nil && *v.LeaseGeneration != 0 && *v.LeaseGeneration < 1 {
|
||||
violations = append(violations, FieldViolation{Field: "lease_generation", Code: "minimum"})
|
||||
}
|
||||
if v.CurrentAppliedRevision != nil && *v.CurrentAppliedRevision != 0 && *v.CurrentAppliedRevision < 0 {
|
||||
violations = append(violations, FieldViolation{Field: "current_applied_revision", Code: "minimum"})
|
||||
}
|
||||
if v.Acquisition == "poll" && (v.OperationID != "" || v.Revision != nil || v.LeaseGeneration != nil || v.CurrentAppliedRevision != nil) {
|
||||
violations = append(violations, FieldViolation{Field: "acquisition", Code: "invalid_tagged_value"})
|
||||
}
|
||||
if v.Acquisition == "prompt" && (v.OperationID == "" || v.Revision == nil || v.LeaseGeneration != nil || v.CurrentAppliedRevision != nil) {
|
||||
violations = append(violations, FieldViolation{Field: "acquisition", Code: "invalid_tagged_value"})
|
||||
}
|
||||
if v.Acquisition == "observation" && (v.OperationID == "" || v.Revision == nil || v.LeaseGeneration == nil || v.CurrentAppliedRevision == nil) {
|
||||
violations = append(violations, FieldViolation{Field: "acquisition", Code: "invalid_tagged_value"})
|
||||
}
|
||||
if len(violations) > 0 {
|
||||
return ValidationError{Violations: violations}
|
||||
}
|
||||
@@ -3771,18 +3812,15 @@ func DecodeGatewayQualityWorkRequest(data []byte) (GatewayQualityWorkRequest, er
|
||||
if err := json.Unmarshal(data, &fields); err != nil {
|
||||
return value, err
|
||||
}
|
||||
if raw, ok := fields["acquisition"]; !ok || bytes.Equal(bytes.TrimSpace(raw), []byte("null")) {
|
||||
return value, ValidationError{Violations: []FieldViolation{{Field: "acquisition", Code: "required"}}}
|
||||
}
|
||||
if raw, ok := fields["gateway_id"]; !ok || bytes.Equal(bytes.TrimSpace(raw), []byte("null")) {
|
||||
return value, ValidationError{Violations: []FieldViolation{{Field: "gateway_id", Code: "required"}}}
|
||||
}
|
||||
if raw, ok := fields["operation_id"]; !ok || bytes.Equal(bytes.TrimSpace(raw), []byte("null")) {
|
||||
return value, ValidationError{Violations: []FieldViolation{{Field: "operation_id", Code: "required"}}}
|
||||
}
|
||||
if raw, ok := fields["reconnect_sequence"]; !ok || bytes.Equal(bytes.TrimSpace(raw), []byte("null")) {
|
||||
return value, ValidationError{Violations: []FieldViolation{{Field: "reconnect_sequence", Code: "required"}}}
|
||||
}
|
||||
if raw, ok := fields["revision"]; !ok || bytes.Equal(bytes.TrimSpace(raw), []byte("null")) {
|
||||
return value, ValidationError{Violations: []FieldViolation{{Field: "revision", Code: "required"}}}
|
||||
}
|
||||
if raw, ok := fields["session_id"]; !ok || bytes.Equal(bytes.TrimSpace(raw), []byte("null")) {
|
||||
return value, ValidationError{Violations: []FieldViolation{{Field: "session_id", Code: "required"}}}
|
||||
}
|
||||
@@ -4273,8 +4311,11 @@ func (v GatewayStopWorkRequest) Validate() error {
|
||||
if v.ReconnectSequence != 0 && v.ReconnectSequence < 0 {
|
||||
violations = append(violations, FieldViolation{Field: "reconnect_sequence", Code: "minimum"})
|
||||
}
|
||||
if v.OperationID == "" {
|
||||
violations = append(violations, FieldViolation{Field: "operation_id", Code: "required"})
|
||||
if v.Acquisition == "" {
|
||||
violations = append(violations, FieldViolation{Field: "acquisition", Code: "required"})
|
||||
}
|
||||
if v.Acquisition != "" && !(v.Acquisition == "poll" || v.Acquisition == "prompt") {
|
||||
violations = append(violations, FieldViolation{Field: "acquisition", Code: "invalid_value"})
|
||||
}
|
||||
if len(v.OperationID) < 36 && v.OperationID != "" {
|
||||
violations = append(violations, FieldViolation{Field: "operation_id", Code: "min_length"})
|
||||
@@ -4285,6 +4326,9 @@ func (v GatewayStopWorkRequest) Validate() error {
|
||||
if v.OperationID != "" && !validCanonicalUUID(v.OperationID) {
|
||||
violations = append(violations, FieldViolation{Field: "operation_id", Code: "invalid_uuid"})
|
||||
}
|
||||
if v.Acquisition == "poll" && v.OperationID != "" || v.Acquisition == "prompt" && v.OperationID == "" {
|
||||
violations = append(violations, FieldViolation{Field: "acquisition", Code: "invalid_tagged_value"})
|
||||
}
|
||||
if len(violations) > 0 {
|
||||
return ValidationError{Violations: violations}
|
||||
}
|
||||
@@ -4303,12 +4347,12 @@ func DecodeGatewayStopWorkRequest(data []byte) (GatewayStopWorkRequest, error) {
|
||||
if err := json.Unmarshal(data, &fields); err != nil {
|
||||
return value, err
|
||||
}
|
||||
if raw, ok := fields["acquisition"]; !ok || bytes.Equal(bytes.TrimSpace(raw), []byte("null")) {
|
||||
return value, ValidationError{Violations: []FieldViolation{{Field: "acquisition", Code: "required"}}}
|
||||
}
|
||||
if raw, ok := fields["gateway_id"]; !ok || bytes.Equal(bytes.TrimSpace(raw), []byte("null")) {
|
||||
return value, ValidationError{Violations: []FieldViolation{{Field: "gateway_id", Code: "required"}}}
|
||||
}
|
||||
if raw, ok := fields["operation_id"]; !ok || bytes.Equal(bytes.TrimSpace(raw), []byte("null")) {
|
||||
return value, ValidationError{Violations: []FieldViolation{{Field: "operation_id", Code: "required"}}}
|
||||
}
|
||||
if raw, ok := fields["reconnect_sequence"]; !ok || bytes.Equal(bytes.TrimSpace(raw), []byte("null")) {
|
||||
return value, ValidationError{Violations: []FieldViolation{{Field: "reconnect_sequence", Code: "required"}}}
|
||||
}
|
||||
|
||||
+2
-2
@@ -12,7 +12,7 @@
|
||||
"3"
|
||||
]
|
||||
},
|
||||
"generator_sha256": "9f6e95fac0f3c8389d8111e6ba0a03b48e155b71e345a11640ef824b8b3a4910",
|
||||
"generator_sha256": "c5756780f59a82d8f56762e52f58e22a4d6aca6648157f45e5bad6559b9deeec",
|
||||
"protocol_version": "1.0.0",
|
||||
"schema_sha256": "614fa11dd1f49b8e10bf21b8c10eadbc1468d16bfcc6ed0a26d29671a5e61300"
|
||||
"schema_sha256": "8c1ed430127cf5774a919f14ff4770b2509d322c8518bf30c412e1e89eeffced"
|
||||
}
|
||||
|
||||
Binary file not shown.
+58
-28
@@ -1,6 +1,6 @@
|
||||
// Code generated by tools/generate.py; DO NOT EDIT.
|
||||
#![allow(non_snake_case)]
|
||||
pub const SCHEMA_SHA256: &str = "614fa11dd1f49b8e10bf21b8c10eadbc1468d16bfcc6ed0a26d29671a5e61300";
|
||||
pub const SCHEMA_SHA256: &str = "8c1ed430127cf5774a919f14ff4770b2509d322c8518bf30c412e1e89eeffced";
|
||||
pub const CURRENT_WIRE_VERSION: &str = "2";
|
||||
pub const N_MINUS_1_WIRE_VERSION: &str = "1";
|
||||
pub const N_MINUS_2_WIRE_VERSION: &str = "0";
|
||||
@@ -1055,14 +1055,15 @@ pub struct GatewayQualityAck {
|
||||
reconnectSequence: i64,
|
||||
operationId: String,
|
||||
revision: i64,
|
||||
leaseGeneration: i64,
|
||||
outcome: String,
|
||||
currentAppliedRevision: i64,
|
||||
currentAppliedRevision: Option<i64>,
|
||||
failureCode: Option<String>,
|
||||
}
|
||||
|
||||
impl GatewayQualityAck {
|
||||
pub fn new(version: String, sessionId: String, gatewayId: String, reconnectSequence: i64, operationId: String, revision: i64, outcome: String, currentAppliedRevision: i64, failureCode: Option<String>) -> Result<Self, ValidationError> {
|
||||
let value = Self { version, sessionId, gatewayId, reconnectSequence, operationId, revision, outcome, currentAppliedRevision, failureCode };
|
||||
pub fn new(version: String, sessionId: String, gatewayId: String, reconnectSequence: i64, operationId: String, revision: i64, leaseGeneration: i64, outcome: String, currentAppliedRevision: Option<i64>, failureCode: Option<String>) -> Result<Self, ValidationError> {
|
||||
let value = Self { version, sessionId, gatewayId, reconnectSequence, operationId, revision, leaseGeneration, outcome, currentAppliedRevision, failureCode };
|
||||
value.validate()?;
|
||||
Ok(value)
|
||||
}
|
||||
@@ -1080,12 +1081,18 @@ impl GatewayQualityAck {
|
||||
if self.operationId.len() > 36 { return Err(ValidationError::new("operation_id", "max_length")); }
|
||||
if !valid_canonical_uuid(self.operationId.as_str()) { return Err(ValidationError::new("operation_id", "invalid_uuid")); }
|
||||
if self.revision < 1 { return Err(ValidationError::new("revision", "minimum")); }
|
||||
if self.outcome != "applied" && self.outcome != "not_applied" && self.outcome != "uncertain" { return Err(ValidationError::new("outcome", "invalid_value")); }
|
||||
if self.currentAppliedRevision < 0 { return Err(ValidationError::new("current_applied_revision", "minimum")); }
|
||||
if self.leaseGeneration < 1 { return Err(ValidationError::new("lease_generation", "minimum")); }
|
||||
if self.outcome != "applied" && self.outcome != "proven_prior" && self.outcome != "unknown" { return Err(ValidationError::new("outcome", "invalid_value")); }
|
||||
if let Some(value) = &self.currentAppliedRevision {
|
||||
if *value < 0 { return Err(ValidationError::new("current_applied_revision", "minimum")); }
|
||||
}
|
||||
if let Some(value) = &self.failureCode {
|
||||
if !value.is_empty() && value.len() < 1 { return Err(ValidationError::new("failure_code", "min_length")); }
|
||||
if value.len() > 128 { return Err(ValidationError::new("failure_code", "max_length")); }
|
||||
}
|
||||
if self.outcome == "applied" && self.currentAppliedRevision != Some(self.revision) { return Err(ValidationError::new("current_applied_revision", "invalid_tagged_value")); }
|
||||
if self.outcome == "proven_prior" && self.currentAppliedRevision.map_or(true, |current| current >= self.revision) { return Err(ValidationError::new("current_applied_revision", "invalid_tagged_value")); }
|
||||
if self.outcome == "unknown" && self.currentAppliedRevision.is_some() { return Err(ValidationError::new("current_applied_revision", "invalid_tagged_value")); }
|
||||
Ok(())
|
||||
}
|
||||
pub fn version(&self) -> &String { &self.version }
|
||||
@@ -1094,8 +1101,9 @@ impl GatewayQualityAck {
|
||||
pub fn reconnectSequence(&self) -> &i64 { &self.reconnectSequence }
|
||||
pub fn operationId(&self) -> &String { &self.operationId }
|
||||
pub fn revision(&self) -> &i64 { &self.revision }
|
||||
pub fn leaseGeneration(&self) -> &i64 { &self.leaseGeneration }
|
||||
pub fn outcome(&self) -> &String { &self.outcome }
|
||||
pub fn currentAppliedRevision(&self) -> &i64 { &self.currentAppliedRevision }
|
||||
pub fn currentAppliedRevision(&self) -> &Option<i64> { &self.currentAppliedRevision }
|
||||
pub fn failureCode(&self) -> &Option<String> { &self.failureCode }
|
||||
}
|
||||
|
||||
@@ -1107,14 +1115,15 @@ pub struct GatewayQualityWork {
|
||||
reconnectSequence: i64,
|
||||
operationId: String,
|
||||
revision: i64,
|
||||
leaseGeneration: i64,
|
||||
leaseExpiresAt: String,
|
||||
selectedDescriptor: SelectedSessionDescriptor,
|
||||
currentAppliedRevision: Option<i64>,
|
||||
}
|
||||
|
||||
impl GatewayQualityWork {
|
||||
pub fn new(version: String, sessionId: String, gatewayId: String, reconnectSequence: i64, operationId: String, revision: i64, leaseExpiresAt: String, selectedDescriptor: SelectedSessionDescriptor, currentAppliedRevision: Option<i64>) -> Result<Self, ValidationError> {
|
||||
let value = Self { version, sessionId, gatewayId, reconnectSequence, operationId, revision, leaseExpiresAt, selectedDescriptor, currentAppliedRevision };
|
||||
pub fn new(version: String, sessionId: String, gatewayId: String, reconnectSequence: i64, operationId: String, revision: i64, leaseGeneration: i64, leaseExpiresAt: String, selectedDescriptor: SelectedSessionDescriptor, currentAppliedRevision: Option<i64>) -> Result<Self, ValidationError> {
|
||||
let value = Self { version, sessionId, gatewayId, reconnectSequence, operationId, revision, leaseGeneration, leaseExpiresAt, selectedDescriptor, currentAppliedRevision };
|
||||
value.validate()?;
|
||||
Ok(value)
|
||||
}
|
||||
@@ -1132,6 +1141,7 @@ impl GatewayQualityWork {
|
||||
if self.operationId.len() > 36 { return Err(ValidationError::new("operation_id", "max_length")); }
|
||||
if !valid_canonical_uuid(self.operationId.as_str()) { return Err(ValidationError::new("operation_id", "invalid_uuid")); }
|
||||
if self.revision < 1 { return Err(ValidationError::new("revision", "minimum")); }
|
||||
if self.leaseGeneration < 1 { return Err(ValidationError::new("lease_generation", "minimum")); }
|
||||
if self.leaseExpiresAt.len() > 64 { return Err(ValidationError::new("lease_expires_at", "max_length")); }
|
||||
if !valid_rfc3339_utc(self.leaseExpiresAt.as_str()) { return Err(ValidationError::new("lease_expires_at", "invalid_time")); }
|
||||
self.selectedDescriptor.validate().map_err(|_| ValidationError::new("selected_descriptor", "invalid_object"))?;
|
||||
@@ -1146,6 +1156,7 @@ impl GatewayQualityWork {
|
||||
pub fn reconnectSequence(&self) -> &i64 { &self.reconnectSequence }
|
||||
pub fn operationId(&self) -> &String { &self.operationId }
|
||||
pub fn revision(&self) -> &i64 { &self.revision }
|
||||
pub fn leaseGeneration(&self) -> &i64 { &self.leaseGeneration }
|
||||
pub fn leaseExpiresAt(&self) -> &String { &self.leaseExpiresAt }
|
||||
pub fn selectedDescriptor(&self) -> &SelectedSessionDescriptor { &self.selectedDescriptor }
|
||||
pub fn currentAppliedRevision(&self) -> &Option<i64> { &self.currentAppliedRevision }
|
||||
@@ -1157,14 +1168,16 @@ pub struct GatewayQualityWorkRequest {
|
||||
sessionId: String,
|
||||
gatewayId: String,
|
||||
reconnectSequence: i64,
|
||||
operationId: String,
|
||||
revision: i64,
|
||||
acquisition: String,
|
||||
operationId: Option<String>,
|
||||
revision: Option<i64>,
|
||||
leaseGeneration: Option<i64>,
|
||||
currentAppliedRevision: Option<i64>,
|
||||
}
|
||||
|
||||
impl GatewayQualityWorkRequest {
|
||||
pub fn new(version: String, sessionId: String, gatewayId: String, reconnectSequence: i64, operationId: String, revision: i64, currentAppliedRevision: Option<i64>) -> Result<Self, ValidationError> {
|
||||
let value = Self { version, sessionId, gatewayId, reconnectSequence, operationId, revision, currentAppliedRevision };
|
||||
pub fn new(version: String, sessionId: String, gatewayId: String, reconnectSequence: i64, acquisition: String, operationId: Option<String>, revision: Option<i64>, leaseGeneration: Option<i64>, currentAppliedRevision: Option<i64>) -> Result<Self, ValidationError> {
|
||||
let value = Self { version, sessionId, gatewayId, reconnectSequence, acquisition, operationId, revision, leaseGeneration, currentAppliedRevision };
|
||||
value.validate()?;
|
||||
Ok(value)
|
||||
}
|
||||
@@ -1177,22 +1190,34 @@ impl GatewayQualityWorkRequest {
|
||||
if !self.gatewayId.is_empty() && self.gatewayId.len() < 1 { return Err(ValidationError::new("gateway_id", "min_length")); }
|
||||
if self.gatewayId.len() > 128 { return Err(ValidationError::new("gateway_id", "max_length")); }
|
||||
if self.reconnectSequence < 0 { return Err(ValidationError::new("reconnect_sequence", "minimum")); }
|
||||
if self.operationId.is_empty() { return Err(ValidationError::new("operation_id", "required")); }
|
||||
if !self.operationId.is_empty() && self.operationId.len() < 36 { return Err(ValidationError::new("operation_id", "min_length")); }
|
||||
if self.operationId.len() > 36 { return Err(ValidationError::new("operation_id", "max_length")); }
|
||||
if !valid_canonical_uuid(self.operationId.as_str()) { return Err(ValidationError::new("operation_id", "invalid_uuid")); }
|
||||
if self.revision < 1 { return Err(ValidationError::new("revision", "minimum")); }
|
||||
if self.acquisition != "poll" && self.acquisition != "prompt" && self.acquisition != "observation" { return Err(ValidationError::new("acquisition", "invalid_value")); }
|
||||
if let Some(value) = &self.operationId {
|
||||
if !value.is_empty() && value.len() < 36 { return Err(ValidationError::new("operation_id", "min_length")); }
|
||||
if value.len() > 36 { return Err(ValidationError::new("operation_id", "max_length")); }
|
||||
if !valid_canonical_uuid(value.as_str()) { return Err(ValidationError::new("operation_id", "invalid_uuid")); }
|
||||
}
|
||||
if let Some(value) = &self.revision {
|
||||
if *value < 1 { return Err(ValidationError::new("revision", "minimum")); }
|
||||
}
|
||||
if let Some(value) = &self.leaseGeneration {
|
||||
if *value < 1 { return Err(ValidationError::new("lease_generation", "minimum")); }
|
||||
}
|
||||
if let Some(value) = &self.currentAppliedRevision {
|
||||
if *value < 0 { return Err(ValidationError::new("current_applied_revision", "minimum")); }
|
||||
}
|
||||
if self.acquisition == "poll" && (self.operationId.is_some() || self.revision.is_some() || self.leaseGeneration.is_some() || self.currentAppliedRevision.is_some()) { return Err(ValidationError::new("acquisition", "invalid_tagged_value")); }
|
||||
if self.acquisition == "prompt" && (self.operationId.is_none() || self.revision.is_none() || self.leaseGeneration.is_some() || self.currentAppliedRevision.is_some()) { return Err(ValidationError::new("acquisition", "invalid_tagged_value")); }
|
||||
if self.acquisition == "observation" && (self.operationId.is_none() || self.revision.is_none() || self.leaseGeneration.is_none() || self.currentAppliedRevision.is_none()) { return Err(ValidationError::new("acquisition", "invalid_tagged_value")); }
|
||||
Ok(())
|
||||
}
|
||||
pub fn version(&self) -> &String { &self.version }
|
||||
pub fn sessionId(&self) -> &String { &self.sessionId }
|
||||
pub fn gatewayId(&self) -> &String { &self.gatewayId }
|
||||
pub fn reconnectSequence(&self) -> &i64 { &self.reconnectSequence }
|
||||
pub fn operationId(&self) -> &String { &self.operationId }
|
||||
pub fn revision(&self) -> &i64 { &self.revision }
|
||||
pub fn acquisition(&self) -> &String { &self.acquisition }
|
||||
pub fn operationId(&self) -> &Option<String> { &self.operationId }
|
||||
pub fn revision(&self) -> &Option<i64> { &self.revision }
|
||||
pub fn leaseGeneration(&self) -> &Option<i64> { &self.leaseGeneration }
|
||||
pub fn currentAppliedRevision(&self) -> &Option<i64> { &self.currentAppliedRevision }
|
||||
}
|
||||
|
||||
@@ -1362,12 +1387,13 @@ pub struct GatewayStopWorkRequest {
|
||||
sessionId: String,
|
||||
gatewayId: String,
|
||||
reconnectSequence: i64,
|
||||
operationId: String,
|
||||
acquisition: String,
|
||||
operationId: Option<String>,
|
||||
}
|
||||
|
||||
impl GatewayStopWorkRequest {
|
||||
pub fn new(version: String, sessionId: String, gatewayId: String, reconnectSequence: i64, operationId: String) -> Result<Self, ValidationError> {
|
||||
let value = Self { version, sessionId, gatewayId, reconnectSequence, operationId };
|
||||
pub fn new(version: String, sessionId: String, gatewayId: String, reconnectSequence: i64, acquisition: String, operationId: Option<String>) -> Result<Self, ValidationError> {
|
||||
let value = Self { version, sessionId, gatewayId, reconnectSequence, acquisition, operationId };
|
||||
value.validate()?;
|
||||
Ok(value)
|
||||
}
|
||||
@@ -1380,17 +1406,21 @@ impl GatewayStopWorkRequest {
|
||||
if !self.gatewayId.is_empty() && self.gatewayId.len() < 1 { return Err(ValidationError::new("gateway_id", "min_length")); }
|
||||
if self.gatewayId.len() > 128 { return Err(ValidationError::new("gateway_id", "max_length")); }
|
||||
if self.reconnectSequence < 0 { return Err(ValidationError::new("reconnect_sequence", "minimum")); }
|
||||
if self.operationId.is_empty() { return Err(ValidationError::new("operation_id", "required")); }
|
||||
if !self.operationId.is_empty() && self.operationId.len() < 36 { return Err(ValidationError::new("operation_id", "min_length")); }
|
||||
if self.operationId.len() > 36 { return Err(ValidationError::new("operation_id", "max_length")); }
|
||||
if !valid_canonical_uuid(self.operationId.as_str()) { return Err(ValidationError::new("operation_id", "invalid_uuid")); }
|
||||
if self.acquisition != "poll" && self.acquisition != "prompt" { return Err(ValidationError::new("acquisition", "invalid_value")); }
|
||||
if let Some(value) = &self.operationId {
|
||||
if !value.is_empty() && value.len() < 36 { return Err(ValidationError::new("operation_id", "min_length")); }
|
||||
if value.len() > 36 { return Err(ValidationError::new("operation_id", "max_length")); }
|
||||
if !valid_canonical_uuid(value.as_str()) { return Err(ValidationError::new("operation_id", "invalid_uuid")); }
|
||||
}
|
||||
if self.acquisition == "poll" && self.operationId.is_some() || self.acquisition == "prompt" && self.operationId.is_none() { return Err(ValidationError::new("acquisition", "invalid_tagged_value")); }
|
||||
Ok(())
|
||||
}
|
||||
pub fn version(&self) -> &String { &self.version }
|
||||
pub fn sessionId(&self) -> &String { &self.sessionId }
|
||||
pub fn gatewayId(&self) -> &String { &self.gatewayId }
|
||||
pub fn reconnectSequence(&self) -> &i64 { &self.reconnectSequence }
|
||||
pub fn operationId(&self) -> &String { &self.operationId }
|
||||
pub fn acquisition(&self) -> &String { &self.acquisition }
|
||||
pub fn operationId(&self) -> &Option<String> { &self.operationId }
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
|
||||
+65
-28
@@ -1,13 +1,14 @@
|
||||
// Code generated by tools/generate.py; DO NOT EDIT.
|
||||
import Foundation
|
||||
public typealias JSONObject = [String: String]
|
||||
public let schemaSHA256 = "614fa11dd1f49b8e10bf21b8c10eadbc1468d16bfcc6ed0a26d29671a5e61300"
|
||||
public let schemaSHA256 = "8c1ed430127cf5774a919f14ff4770b2509d322c8518bf30c412e1e89eeffced"
|
||||
public let currentWireVersion = "2"
|
||||
public let nMinus1WireVersion = "1"
|
||||
public let nMinus2WireVersion = "0"
|
||||
public struct ContractValidationError: Error, Equatable { public let field: String; public let code: String }
|
||||
private struct AnyCodingKey: CodingKey { let stringValue: String; let intValue: Int?; init?(stringValue: String) { self.stringValue = stringValue; self.intValue = nil }; init?(intValue: Int) { self.stringValue = String(intValue); self.intValue = intValue } }
|
||||
private func rejectDuplicateJSONKeys(_ data: Data) throws {
|
||||
guard data.count <= 1_048_576 else { throw ContractValidationError(field: "json", code: "payload_too_large") }
|
||||
var index = 0
|
||||
func skipWhitespace() { while index < data.count && [9, 10, 13, 32].contains(data[index]) { index += 1 } }
|
||||
func parseString() throws -> String {
|
||||
@@ -21,7 +22,8 @@ private func rejectDuplicateJSONKeys(_ data: Data) throws {
|
||||
}
|
||||
throw ContractValidationError(field: "json", code: "invalid_json")
|
||||
}
|
||||
func parseValue() throws {
|
||||
func parseValue(_ depth: Int) throws {
|
||||
guard depth <= 64 else { throw ContractValidationError(field: "json", code: "nesting_too_deep") }
|
||||
skipWhitespace()
|
||||
guard index < data.count else { throw ContractValidationError(field: "json", code: "invalid_json") }
|
||||
if data[index] == 123 {
|
||||
@@ -36,7 +38,7 @@ private func rejectDuplicateJSONKeys(_ data: Data) throws {
|
||||
skipWhitespace()
|
||||
guard index < data.count, data[index] == 58 else { throw ContractValidationError(field: "json", code: "invalid_json") }
|
||||
index += 1
|
||||
try parseValue()
|
||||
try parseValue(depth + 1)
|
||||
skipWhitespace()
|
||||
guard index < data.count else { throw ContractValidationError(field: "json", code: "invalid_json") }
|
||||
if data[index] == 125 { index += 1; return }
|
||||
@@ -49,7 +51,7 @@ private func rejectDuplicateJSONKeys(_ data: Data) throws {
|
||||
skipWhitespace()
|
||||
if index < data.count, data[index] == 93 { index += 1; return }
|
||||
while true {
|
||||
try parseValue()
|
||||
try parseValue(depth + 1)
|
||||
skipWhitespace()
|
||||
guard index < data.count else { throw ContractValidationError(field: "json", code: "invalid_json") }
|
||||
if data[index] == 93 { index += 1; return }
|
||||
@@ -62,7 +64,7 @@ private func rejectDuplicateJSONKeys(_ data: Data) throws {
|
||||
while index < data.count && ![9, 10, 13, 32, 44, 93, 125].contains(data[index]) { index += 1 }
|
||||
guard index > start else { throw ContractValidationError(field: "json", code: "invalid_json") }
|
||||
}
|
||||
try parseValue()
|
||||
try parseValue(0)
|
||||
skipWhitespace()
|
||||
guard index == data.count else { throw ContractValidationError(field: "json", code: "trailing_json") }
|
||||
}
|
||||
@@ -1434,8 +1436,9 @@ public struct GatewayQualityAck: Codable, Equatable {
|
||||
public let reconnectSequence: Int64
|
||||
public let operationId: String
|
||||
public let revision: Int64
|
||||
public let leaseGeneration: Int64
|
||||
public let outcome: String
|
||||
public let currentAppliedRevision: Int64
|
||||
public let currentAppliedRevision: Int64?
|
||||
public let failureCode: String?
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case version = "version"
|
||||
@@ -1444,18 +1447,20 @@ public struct GatewayQualityAck: Codable, Equatable {
|
||||
case reconnectSequence = "reconnect_sequence"
|
||||
case operationId = "operation_id"
|
||||
case revision = "revision"
|
||||
case leaseGeneration = "lease_generation"
|
||||
case outcome = "outcome"
|
||||
case currentAppliedRevision = "current_applied_revision"
|
||||
case failureCode = "failure_code"
|
||||
}
|
||||
|
||||
public init(version: String, sessionId: String, gatewayId: String, reconnectSequence: Int64, operationId: String, revision: Int64, outcome: String, currentAppliedRevision: Int64, failureCode: String?) throws {
|
||||
public init(version: String, sessionId: String, gatewayId: String, reconnectSequence: Int64, operationId: String, revision: Int64, leaseGeneration: Int64, outcome: String, currentAppliedRevision: Int64?, failureCode: String?) throws {
|
||||
self.version = version
|
||||
self.sessionId = sessionId
|
||||
self.gatewayId = gatewayId
|
||||
self.reconnectSequence = reconnectSequence
|
||||
self.operationId = operationId
|
||||
self.revision = revision
|
||||
self.leaseGeneration = leaseGeneration
|
||||
self.outcome = outcome
|
||||
self.currentAppliedRevision = currentAppliedRevision
|
||||
self.failureCode = failureCode
|
||||
@@ -1466,7 +1471,7 @@ public struct GatewayQualityAck: Codable, Equatable {
|
||||
let all = try decoder.container(keyedBy: AnyCodingKey.self)
|
||||
for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") }
|
||||
let c = try decoder.container(keyedBy: CodingKeys.self)
|
||||
try self.init(version: try c.decode(String.self, forKey: .version), sessionId: try c.decode(String.self, forKey: .sessionId), gatewayId: try c.decode(String.self, forKey: .gatewayId), reconnectSequence: try c.decode(Int64.self, forKey: .reconnectSequence), operationId: try c.decode(String.self, forKey: .operationId), revision: try c.decode(Int64.self, forKey: .revision), outcome: try c.decode(String.self, forKey: .outcome), currentAppliedRevision: try c.decode(Int64.self, forKey: .currentAppliedRevision), failureCode: try c.decodeIfPresent(String.self, forKey: .failureCode))
|
||||
try self.init(version: try c.decode(String.self, forKey: .version), sessionId: try c.decode(String.self, forKey: .sessionId), gatewayId: try c.decode(String.self, forKey: .gatewayId), reconnectSequence: try c.decode(Int64.self, forKey: .reconnectSequence), operationId: try c.decode(String.self, forKey: .operationId), revision: try c.decode(Int64.self, forKey: .revision), leaseGeneration: try c.decode(Int64.self, forKey: .leaseGeneration), outcome: try c.decode(String.self, forKey: .outcome), currentAppliedRevision: try c.decodeIfPresent(Int64.self, forKey: .currentAppliedRevision), failureCode: try c.decodeIfPresent(String.self, forKey: .failureCode))
|
||||
}
|
||||
|
||||
public func validate() throws {
|
||||
@@ -1483,12 +1488,18 @@ public struct GatewayQualityAck: Codable, Equatable {
|
||||
if self.operationId.utf8.count > 36 { throw ContractValidationError(field: "operation_id", code: "max_length") }
|
||||
if !validCanonicalUUID(self.operationId) { throw ContractValidationError(field: "operation_id", code: "invalid_uuid") }
|
||||
if self.revision < 1 { throw ContractValidationError(field: "revision", code: "minimum") }
|
||||
if !["applied", "not_applied", "uncertain"].contains(self.outcome) { throw ContractValidationError(field: "outcome", code: "invalid_value") }
|
||||
if self.currentAppliedRevision < 0 { throw ContractValidationError(field: "current_applied_revision", code: "minimum") }
|
||||
if self.leaseGeneration < 1 { throw ContractValidationError(field: "lease_generation", code: "minimum") }
|
||||
if !["applied", "proven_prior", "unknown"].contains(self.outcome) { throw ContractValidationError(field: "outcome", code: "invalid_value") }
|
||||
if let value = self.currentAppliedRevision {
|
||||
if value < 0 { throw ContractValidationError(field: "current_applied_revision", code: "minimum") }
|
||||
}
|
||||
if let value = self.failureCode {
|
||||
if !value.isEmpty && value.utf8.count < 1 { throw ContractValidationError(field: "failure_code", code: "min_length") }
|
||||
if value.utf8.count > 128 { throw ContractValidationError(field: "failure_code", code: "max_length") }
|
||||
}
|
||||
if outcome == "applied" && currentAppliedRevision != revision { throw ContractValidationError(field: "current_applied_revision", code: "invalid_tagged_value") }
|
||||
if outcome == "proven_prior" && (currentAppliedRevision == nil || currentAppliedRevision! >= revision) { throw ContractValidationError(field: "current_applied_revision", code: "invalid_tagged_value") }
|
||||
if outcome == "unknown" && currentAppliedRevision != nil { throw ContractValidationError(field: "current_applied_revision", code: "invalid_tagged_value") }
|
||||
}
|
||||
|
||||
public static func decodeJSON(_ data: Data) throws -> Self { try rejectDuplicateJSONKeys(data); return try JSONDecoder().decode(Self.self, from: data) }
|
||||
@@ -1502,6 +1513,7 @@ public struct GatewayQualityWork: Codable, Equatable {
|
||||
public let reconnectSequence: Int64
|
||||
public let operationId: String
|
||||
public let revision: Int64
|
||||
public let leaseGeneration: Int64
|
||||
public let leaseExpiresAt: String
|
||||
public let selectedDescriptor: SelectedSessionDescriptor
|
||||
public let currentAppliedRevision: Int64?
|
||||
@@ -1512,18 +1524,20 @@ public struct GatewayQualityWork: Codable, Equatable {
|
||||
case reconnectSequence = "reconnect_sequence"
|
||||
case operationId = "operation_id"
|
||||
case revision = "revision"
|
||||
case leaseGeneration = "lease_generation"
|
||||
case leaseExpiresAt = "lease_expires_at"
|
||||
case selectedDescriptor = "selected_descriptor"
|
||||
case currentAppliedRevision = "current_applied_revision"
|
||||
}
|
||||
|
||||
public init(version: String, sessionId: String, gatewayId: String, reconnectSequence: Int64, operationId: String, revision: Int64, leaseExpiresAt: String, selectedDescriptor: SelectedSessionDescriptor, currentAppliedRevision: Int64?) throws {
|
||||
public init(version: String, sessionId: String, gatewayId: String, reconnectSequence: Int64, operationId: String, revision: Int64, leaseGeneration: Int64, leaseExpiresAt: String, selectedDescriptor: SelectedSessionDescriptor, currentAppliedRevision: Int64?) throws {
|
||||
self.version = version
|
||||
self.sessionId = sessionId
|
||||
self.gatewayId = gatewayId
|
||||
self.reconnectSequence = reconnectSequence
|
||||
self.operationId = operationId
|
||||
self.revision = revision
|
||||
self.leaseGeneration = leaseGeneration
|
||||
self.leaseExpiresAt = leaseExpiresAt
|
||||
self.selectedDescriptor = selectedDescriptor
|
||||
self.currentAppliedRevision = currentAppliedRevision
|
||||
@@ -1534,7 +1548,7 @@ public struct GatewayQualityWork: Codable, Equatable {
|
||||
let all = try decoder.container(keyedBy: AnyCodingKey.self)
|
||||
for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") }
|
||||
let c = try decoder.container(keyedBy: CodingKeys.self)
|
||||
try self.init(version: try c.decode(String.self, forKey: .version), sessionId: try c.decode(String.self, forKey: .sessionId), gatewayId: try c.decode(String.self, forKey: .gatewayId), reconnectSequence: try c.decode(Int64.self, forKey: .reconnectSequence), operationId: try c.decode(String.self, forKey: .operationId), revision: try c.decode(Int64.self, forKey: .revision), leaseExpiresAt: try c.decode(String.self, forKey: .leaseExpiresAt), selectedDescriptor: try c.decode(SelectedSessionDescriptor.self, forKey: .selectedDescriptor), currentAppliedRevision: try c.decodeIfPresent(Int64.self, forKey: .currentAppliedRevision))
|
||||
try self.init(version: try c.decode(String.self, forKey: .version), sessionId: try c.decode(String.self, forKey: .sessionId), gatewayId: try c.decode(String.self, forKey: .gatewayId), reconnectSequence: try c.decode(Int64.self, forKey: .reconnectSequence), operationId: try c.decode(String.self, forKey: .operationId), revision: try c.decode(Int64.self, forKey: .revision), leaseGeneration: try c.decode(Int64.self, forKey: .leaseGeneration), leaseExpiresAt: try c.decode(String.self, forKey: .leaseExpiresAt), selectedDescriptor: try c.decode(SelectedSessionDescriptor.self, forKey: .selectedDescriptor), currentAppliedRevision: try c.decodeIfPresent(Int64.self, forKey: .currentAppliedRevision))
|
||||
}
|
||||
|
||||
public func validate() throws {
|
||||
@@ -1551,6 +1565,7 @@ public struct GatewayQualityWork: Codable, Equatable {
|
||||
if self.operationId.utf8.count > 36 { throw ContractValidationError(field: "operation_id", code: "max_length") }
|
||||
if !validCanonicalUUID(self.operationId) { throw ContractValidationError(field: "operation_id", code: "invalid_uuid") }
|
||||
if self.revision < 1 { throw ContractValidationError(field: "revision", code: "minimum") }
|
||||
if self.leaseGeneration < 1 { throw ContractValidationError(field: "lease_generation", code: "minimum") }
|
||||
if self.leaseExpiresAt.utf8.count > 64 { throw ContractValidationError(field: "lease_expires_at", code: "max_length") }
|
||||
if !validRFC3339UTC(self.leaseExpiresAt) { throw ContractValidationError(field: "lease_expires_at", code: "invalid_time") }
|
||||
try self.selectedDescriptor.validate()
|
||||
@@ -1568,26 +1583,32 @@ public struct GatewayQualityWorkRequest: Codable, Equatable {
|
||||
public let sessionId: String
|
||||
public let gatewayId: String
|
||||
public let reconnectSequence: Int64
|
||||
public let operationId: String
|
||||
public let revision: Int64
|
||||
public let acquisition: String
|
||||
public let operationId: String?
|
||||
public let revision: Int64?
|
||||
public let leaseGeneration: Int64?
|
||||
public let currentAppliedRevision: Int64?
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case version = "version"
|
||||
case sessionId = "session_id"
|
||||
case gatewayId = "gateway_id"
|
||||
case reconnectSequence = "reconnect_sequence"
|
||||
case acquisition = "acquisition"
|
||||
case operationId = "operation_id"
|
||||
case revision = "revision"
|
||||
case leaseGeneration = "lease_generation"
|
||||
case currentAppliedRevision = "current_applied_revision"
|
||||
}
|
||||
|
||||
public init(version: String, sessionId: String, gatewayId: String, reconnectSequence: Int64, operationId: String, revision: Int64, currentAppliedRevision: Int64?) throws {
|
||||
public init(version: String, sessionId: String, gatewayId: String, reconnectSequence: Int64, acquisition: String, operationId: String?, revision: Int64?, leaseGeneration: Int64?, currentAppliedRevision: Int64?) throws {
|
||||
self.version = version
|
||||
self.sessionId = sessionId
|
||||
self.gatewayId = gatewayId
|
||||
self.reconnectSequence = reconnectSequence
|
||||
self.acquisition = acquisition
|
||||
self.operationId = operationId
|
||||
self.revision = revision
|
||||
self.leaseGeneration = leaseGeneration
|
||||
self.currentAppliedRevision = currentAppliedRevision
|
||||
try validate()
|
||||
}
|
||||
@@ -1596,7 +1617,7 @@ public struct GatewayQualityWorkRequest: Codable, Equatable {
|
||||
let all = try decoder.container(keyedBy: AnyCodingKey.self)
|
||||
for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") }
|
||||
let c = try decoder.container(keyedBy: CodingKeys.self)
|
||||
try self.init(version: try c.decode(String.self, forKey: .version), sessionId: try c.decode(String.self, forKey: .sessionId), gatewayId: try c.decode(String.self, forKey: .gatewayId), reconnectSequence: try c.decode(Int64.self, forKey: .reconnectSequence), operationId: try c.decode(String.self, forKey: .operationId), revision: try c.decode(Int64.self, forKey: .revision), currentAppliedRevision: try c.decodeIfPresent(Int64.self, forKey: .currentAppliedRevision))
|
||||
try self.init(version: try c.decode(String.self, forKey: .version), sessionId: try c.decode(String.self, forKey: .sessionId), gatewayId: try c.decode(String.self, forKey: .gatewayId), reconnectSequence: try c.decode(Int64.self, forKey: .reconnectSequence), acquisition: try c.decode(String.self, forKey: .acquisition), operationId: try c.decodeIfPresent(String.self, forKey: .operationId), revision: try c.decodeIfPresent(Int64.self, forKey: .revision), leaseGeneration: try c.decodeIfPresent(Int64.self, forKey: .leaseGeneration), currentAppliedRevision: try c.decodeIfPresent(Int64.self, forKey: .currentAppliedRevision))
|
||||
}
|
||||
|
||||
public func validate() throws {
|
||||
@@ -1608,14 +1629,24 @@ public struct GatewayQualityWorkRequest: Codable, Equatable {
|
||||
if !self.gatewayId.isEmpty && self.gatewayId.utf8.count < 1 { throw ContractValidationError(field: "gateway_id", code: "min_length") }
|
||||
if self.gatewayId.utf8.count > 128 { throw ContractValidationError(field: "gateway_id", code: "max_length") }
|
||||
if self.reconnectSequence < 0 { throw ContractValidationError(field: "reconnect_sequence", code: "minimum") }
|
||||
if self.operationId.isEmpty { throw ContractValidationError(field: "operation_id", code: "required") }
|
||||
if !self.operationId.isEmpty && self.operationId.utf8.count < 36 { throw ContractValidationError(field: "operation_id", code: "min_length") }
|
||||
if self.operationId.utf8.count > 36 { throw ContractValidationError(field: "operation_id", code: "max_length") }
|
||||
if !validCanonicalUUID(self.operationId) { throw ContractValidationError(field: "operation_id", code: "invalid_uuid") }
|
||||
if self.revision < 1 { throw ContractValidationError(field: "revision", code: "minimum") }
|
||||
if !["poll", "prompt", "observation"].contains(self.acquisition) { throw ContractValidationError(field: "acquisition", code: "invalid_value") }
|
||||
if let value = self.operationId {
|
||||
if !value.isEmpty && value.utf8.count < 36 { throw ContractValidationError(field: "operation_id", code: "min_length") }
|
||||
if value.utf8.count > 36 { throw ContractValidationError(field: "operation_id", code: "max_length") }
|
||||
if !validCanonicalUUID(value) { throw ContractValidationError(field: "operation_id", code: "invalid_uuid") }
|
||||
}
|
||||
if let value = self.revision {
|
||||
if value < 1 { throw ContractValidationError(field: "revision", code: "minimum") }
|
||||
}
|
||||
if let value = self.leaseGeneration {
|
||||
if value < 1 { throw ContractValidationError(field: "lease_generation", code: "minimum") }
|
||||
}
|
||||
if let value = self.currentAppliedRevision {
|
||||
if value < 0 { throw ContractValidationError(field: "current_applied_revision", code: "minimum") }
|
||||
}
|
||||
if acquisition == "poll" && (operationId != nil || revision != nil || leaseGeneration != nil || currentAppliedRevision != nil) { throw ContractValidationError(field: "acquisition", code: "invalid_tagged_value") }
|
||||
if acquisition == "prompt" && (operationId == nil || revision == nil || leaseGeneration != nil || currentAppliedRevision != nil) { throw ContractValidationError(field: "acquisition", code: "invalid_tagged_value") }
|
||||
if acquisition == "observation" && (operationId == nil || revision == nil || leaseGeneration == nil || currentAppliedRevision == nil) { throw ContractValidationError(field: "acquisition", code: "invalid_tagged_value") }
|
||||
}
|
||||
|
||||
public static func decodeJSON(_ data: Data) throws -> Self { try rejectDuplicateJSONKeys(data); return try JSONDecoder().decode(Self.self, from: data) }
|
||||
@@ -1834,20 +1865,23 @@ public struct GatewayStopWorkRequest: Codable, Equatable {
|
||||
public let sessionId: String
|
||||
public let gatewayId: String
|
||||
public let reconnectSequence: Int64
|
||||
public let operationId: String
|
||||
public let acquisition: String
|
||||
public let operationId: String?
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case version = "version"
|
||||
case sessionId = "session_id"
|
||||
case gatewayId = "gateway_id"
|
||||
case reconnectSequence = "reconnect_sequence"
|
||||
case acquisition = "acquisition"
|
||||
case operationId = "operation_id"
|
||||
}
|
||||
|
||||
public init(version: String, sessionId: String, gatewayId: String, reconnectSequence: Int64, operationId: String) throws {
|
||||
public init(version: String, sessionId: String, gatewayId: String, reconnectSequence: Int64, acquisition: String, operationId: String?) throws {
|
||||
self.version = version
|
||||
self.sessionId = sessionId
|
||||
self.gatewayId = gatewayId
|
||||
self.reconnectSequence = reconnectSequence
|
||||
self.acquisition = acquisition
|
||||
self.operationId = operationId
|
||||
try validate()
|
||||
}
|
||||
@@ -1856,7 +1890,7 @@ public struct GatewayStopWorkRequest: Codable, Equatable {
|
||||
let all = try decoder.container(keyedBy: AnyCodingKey.self)
|
||||
for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") }
|
||||
let c = try decoder.container(keyedBy: CodingKeys.self)
|
||||
try self.init(version: try c.decode(String.self, forKey: .version), sessionId: try c.decode(String.self, forKey: .sessionId), gatewayId: try c.decode(String.self, forKey: .gatewayId), reconnectSequence: try c.decode(Int64.self, forKey: .reconnectSequence), operationId: try c.decode(String.self, forKey: .operationId))
|
||||
try self.init(version: try c.decode(String.self, forKey: .version), sessionId: try c.decode(String.self, forKey: .sessionId), gatewayId: try c.decode(String.self, forKey: .gatewayId), reconnectSequence: try c.decode(Int64.self, forKey: .reconnectSequence), acquisition: try c.decode(String.self, forKey: .acquisition), operationId: try c.decodeIfPresent(String.self, forKey: .operationId))
|
||||
}
|
||||
|
||||
public func validate() throws {
|
||||
@@ -1868,10 +1902,13 @@ public struct GatewayStopWorkRequest: Codable, Equatable {
|
||||
if !self.gatewayId.isEmpty && self.gatewayId.utf8.count < 1 { throw ContractValidationError(field: "gateway_id", code: "min_length") }
|
||||
if self.gatewayId.utf8.count > 128 { throw ContractValidationError(field: "gateway_id", code: "max_length") }
|
||||
if self.reconnectSequence < 0 { throw ContractValidationError(field: "reconnect_sequence", code: "minimum") }
|
||||
if self.operationId.isEmpty { throw ContractValidationError(field: "operation_id", code: "required") }
|
||||
if !self.operationId.isEmpty && self.operationId.utf8.count < 36 { throw ContractValidationError(field: "operation_id", code: "min_length") }
|
||||
if self.operationId.utf8.count > 36 { throw ContractValidationError(field: "operation_id", code: "max_length") }
|
||||
if !validCanonicalUUID(self.operationId) { throw ContractValidationError(field: "operation_id", code: "invalid_uuid") }
|
||||
if !["poll", "prompt"].contains(self.acquisition) { throw ContractValidationError(field: "acquisition", code: "invalid_value") }
|
||||
if let value = self.operationId {
|
||||
if !value.isEmpty && value.utf8.count < 36 { throw ContractValidationError(field: "operation_id", code: "min_length") }
|
||||
if value.utf8.count > 36 { throw ContractValidationError(field: "operation_id", code: "max_length") }
|
||||
if !validCanonicalUUID(value) { throw ContractValidationError(field: "operation_id", code: "invalid_uuid") }
|
||||
}
|
||||
if acquisition == "poll" && operationId != nil || acquisition == "prompt" && operationId == nil { throw ContractValidationError(field: "acquisition", code: "invalid_tagged_value") }
|
||||
}
|
||||
|
||||
public static func decodeJSON(_ data: Data) throws -> Self { try rejectDuplicateJSONKeys(data); return try JSONDecoder().decode(Self.self, from: data) }
|
||||
|
||||
Reference in New Issue
Block a user