/* * Copyright 2023 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ import { Any__Output } from "../generated/google/protobuf/Any"; import { BootstrapInfo, XdsServerConfig } from "../xds-bootstrap"; export interface XdsDecodeContext { server: XdsServerConfig; bootstrap: BootstrapInfo; } export interface XdsDecodeResult { name: string; /** * Mutually exclusive with error. */ value?: object; /** * Mutually exclusive with value. */ error?: string; } type ValueType = string | number | bigint | boolean | undefined | null | symbol | {[key: string]: ValueType} | ValueType[]; function deepEqual(value1: ValueType, value2: ValueType): boolean { if (value1 === value2) { return true; } // Extra null check to narrow type result of typeof value === 'object' if (value1 === null || value2 === null) { // They are not equal per previous check return false; } if (Array.isArray(value1) && Array.isArray(value2)) { if (value1.length !== value2.length) { return false; } for (const [index, entry] of value1.entries()) { if (!deepEqual(entry, value2[index])) { return false; } } return true; } else if (Array.isArray(value1) || Array.isArray(value2)) { return false; } else if (typeof value1 === 'object' && typeof value2 === 'object') { for (const [key, entry] of Object.entries(value1)) { if (!deepEqual(entry, value2[key])) { return false; } } return true; } return false; } export interface ValidationSuccess { valid: true; result: T; } export interface ValidationFailure { valid: false; errors: string[] } export type ValidationResult = ValidationSuccess | ValidationFailure; export abstract class XdsResourceType { /** * The type URL as used in xdstp: names */ abstract getTypeUrl(): string; /** * The type URL as used in the `DiscoveryResponse.type_url` field and the `Any.type_url` field */ getFullTypeUrl(): string { return `type.googleapis.com/${this.getTypeUrl()}`; } abstract decode(context: XdsDecodeContext, resource: Any__Output): XdsDecodeResult; abstract allResourcesRequiredInSotW(): boolean; resourcesEqual(value1: object | null, value2: object | null): boolean { return deepEqual(value1 as ValueType, value2 as ValueType); } }