/*! * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file. */ import { Defer } from '@webex/common'; import { IP_VERSION } from '../constants'; import ReachabilityRequest, { ClusterList } from './request'; import { ClusterReachabilityResult, ClientMediaPreferences, ReachabilityMetrics, ReachabilityReportV0, ReachabilityReportV1, ReachabilityResults, ReachabilityResultsForBackend, GetClustersTrigger, NatType } from './reachability.types'; import { ClusterReachability } from './clusterReachability'; import EventsScope from '../common/events/events-scope'; /** * @class Reachability * @export */ export default class Reachability extends EventsScope { namespace: string; webex: object; reachabilityRequest: ReachabilityRequest; clusterReachability: { [key: string]: ClusterReachability; }; minRequiredClusters?: number; orpheusApiVersion?: number; reachabilityDefer?: Defer; vmnTimer?: ReturnType; publicCloudTimer?: ReturnType; overallTimer?: ReturnType; expectedResultsCount: { videoMesh: { udp: number; }; public: { udp: number; tcp: number; xtls: number; }; }; resultsCount: { videoMesh: { udp: number; }; public: { udp: number; tcp: number; xtls: number; }; }; startTime: any; totalDuration: any; natType: NatType; protected lastTrigger?: string; /** * Creates an instance of Reachability. * @param {object} webex * @memberof Reachability */ constructor(webex: object); /** * Fetches the list of media clusters from the backend * @param {string} trigger - explains the reason for starting reachability, used by Orpheus * @param {Object} previousReport - last reachability report * @param {boolean} isRetry * @private * @returns {Promise<{clusters: ClusterList, joinCookie: any}>} */ getClusters(trigger: GetClustersTrigger, previousReport?: any, isRetry?: boolean): Promise<{ clusters: ClusterList; joinCookie: any; }>; /** * Checks if the given subnet is reachable * @param {string} selectedSubnetFirstOctet - selected subnet first octet, e.g. "10" for "10.X.X.X" * @returns {boolean | null} true if reachable, false if not reachable, null if mediaServerIp is not provided * @public * @memberof Reachability */ isSubnetReachable(selectedSubnetFirstOctet: string): boolean | null; /** * Gets a list of media clusters from the backend and performs reachability checks on all the clusters * @param {string} trigger - explains the reason for starting reachability * @returns {Promise} reachability results * @public * @memberof Reachability */ gatherReachability(trigger: string): Promise; /** * Gets the last join cookie we got from Orpheus * * @returns {Promise} join cookie */ getJoinCookie(): Promise; /** * Returns the reachability report that needs to be attached to the ROAP messages * that we send to the backend. * * @returns {Promise} */ getReachabilityReport(): Promise<{ joinCookie: any; reachability?: ReachabilityReportV1; } | { reachability: ReachabilityReportV0; }>; /** * This method is called when we don't succeed in reaching the minimum number of clusters * required by Orpheus. It sends the results to Orpheus and gets a new list that it tries to reach again. * @returns {Promise} reachability results * @public * @memberof Reachability */ gatherReachabilityFallback(): Promise; /** * Stops all reachability checks that are in progress * @public * @memberof Reachability * @returns {void} */ stopReachability(): void; /** * Returns statistics about last reachability results. The returned value is an object * with a flat list of properties so that it can be easily sent with metrics * * @returns {Promise} Promise with metrics values, it never rejects/throws. */ getReachabilityMetrics(): Promise; /** * Maps our internal transport result to the format that backend expects * @param {TransportResult} transportResult * @returns {TransportResultForBackend} */ private mapTransportResultToBackendDataFormat; /** * Reachability results as an object in the format that backend expects * * @returns {any} reachability results that need to be sent to the backend */ getReachabilityResults(): Promise; /** * fetches reachability data and checks for cluster reachability * @returns {boolean} * @public * @memberof Reachability */ isAnyPublicClusterReachable(): Promise; /** * Returns true only if ALL protocols (UDP, TCP and TLS) have been tested and none * of the media clusters where reachable with any of the protocols. This is done * irrespective of the config, so for example: * if config.meetings.experimental.enableTlsReachability === false, * it will return false, because TLS reachability won't be tested, * so we can't say for sure that media backend is unreachable over TLS. * * @returns {boolean} */ isWebexMediaBackendUnreachable(): Promise; /** * Get list of all unreachable clusters * @returns {array} Unreachable clusters * @private * @memberof Reachability */ private getUnreachableClusters; /** * Gets the number of reachable clusters from last run reachability check * @returns {number} reachable clusters count * @private * @memberof Reachability */ private getNumberOfReachableClusters; /** * Make a log of unreachable clusters. * @returns {undefined} * @private * @memberof Reachability */ private logUnreachableClusters; /** * Returns true if we've obtained all the reachability results for all the public clusters * In other words, it means that all public clusters are reachable over each protocol, * because we only get a "result" if we managed to reach a cluster * * @returns {boolean} */ private areAllPublicClusterResultsReady; /** * Returns true if we've obtained all the reachability results for all the clusters * * @returns {boolean} */ private areAllResultsReady; /** * Resolves the promise returned by gatherReachability() method * @param {boolean} checkMinRequiredClusters - if true, it will check if we have reached the minimum required clusters and do a fallback if needed * @returns {void} */ private resolveReachabilityPromise; /** * Aborts all cluster reachability checks that are in progress * * @returns {void} */ private abortClusterReachability; /** * Helper function for calculating min/max/average values of latency * * @param {Array} results * @param {string} protocol * @param {boolean} isVideoMesh * @returns {{min:number, max: number, average: number}} */ protected getStatistics(results: Array, protocol: 'udp' | 'tcp' | 'xtls', isVideoMesh: boolean): { min: number; max: number; average: number; }; /** * Sends a metric with all the statistics about how long reachability took * * @param {boolean} aborted true if the reachability checks were aborted * @returns {void} */ protected sendMetric(aborted?: boolean): Promise; /** * Starts all the timers used for various timeouts * * @returns {void} */ private startTimers; /** * Stores given reachability results in local storage * * @param {ReachabilityResults} results * @returns {Promise} */ private storeResults; /** * Resets all the internal counters that keep track of the results * * @returns {void} */ private resetResultCounters; /** * Clears the timer * * @param {string} timer name of the timer to clear * @returns {void} */ private clearTimer; /** * Aborts current checks that are in progress * * @returns {void} */ private abortCurrentChecks; /** * Performs reachability checks for all clusters * @param {ClusterList} clusterList * @returns {Promise} promise that's resolved as soon as the checks are started */ private performReachabilityChecks; /** * Returns the clientMediaPreferences object that needs to be sent to the backend * when joining a meeting * * @param {boolean} isMultistream * @param {IP_VERSION} ipver * @returns {Object} */ getClientMediaPreferences(isMultistream: boolean, ipver?: IP_VERSION): Promise; /** * Returns the reachability report that needs to be attached to the ROAP messages * that we send to the backend. * It may return undefined, if reachability is not needed to be attached to ROAP messages (that's the case for v1 or Orpheus API) * * @returns {Promise} object that needs to be attached to Roap messages */ getReachabilityReportToAttachToRoap(): Promise; }