UNPKG

@itwin/reality-data-client

Version:

HTTP Client for the iTwin Platform Reality Management APIs

161 lines 7.69 kB
import { BentleyError } from "@itwin/core-bentley"; import { getRequestConfig } from "./RequestOptions"; import axios from "axios"; /** * Cache parameters for reality data access. Contains the blob url, the timestamp to refresh (every 50 minutes) the url and the root document path. * Cache contains one value for the read permission url, and one of the write permission. * */ class ContainerCache { _containerRead; _containerWrite; getCache(access) { if (access === "Read") return this._containerRead; else return this._containerWrite; } setCache(containerCacheValue, access) { if (access === "Read") this._containerRead = containerCacheValue; else this._containerWrite = containerCacheValue; } } /** RealityData * This class implements a Reality Data instance. * Data is accessed directly through methods of the reality data instance. * Access to the data required a properly entitled token though the access to the blob is controlled through * an Azure blob URL, the token may be required to obtain this Azure blob URL or refresh it. * The Azure blob URL is considered valid for an hour and is refreshed after 50 minutes. * In addition to the reality data properties, and Azure blob URL and internal states, a reality data also contains * the identification of the iTwin to be used for access permissions and * may contain a RealityDataClient to obtain the specialization to communicate with Reality Management API (to obtain the Azure blob URL). * @beta */ export class ITwinRealityData { id; displayName; dataset; group; dataCenterLocation; description; rootDocument; tags; acquisition; size; authoring; classification; type; extent; /** @deprecated in 1.0.1 not used in Reality Management API. Will be removed in next major update.*/ accessControl; // TODO: remove in next major update modifiedDateTime; lastAccessedDateTime; createdDateTime; /** Link to client to fetch the blob url */ client; /** The GUID identifier of the iTwin used when using the client. */ iTwinId; /** Cache parameters for reality data access. Contains the blob url, the timestamp to refresh (every 50 minutes) the url and the root document path. */ _containerCache; /** * Creates an instance of RealityData. * @beta */ constructor(client, realityData, iTwinId) { this.client = client; this._containerCache = new ContainerCache(); if (realityData) { this.id = realityData.id; this.displayName = realityData.displayName; this.dataset = realityData.dataset; this.group = realityData.group; this.dataCenterLocation = realityData.dataCenterLocation; this.description = realityData.description; this.rootDocument = realityData.rootDocument; this.tags = realityData.tags; if (realityData.acquisition) { this.acquisition = realityData.acquisition; this.acquisition.startDateTime = new Date(realityData.acquisition.startDateTime); this.acquisition.endDateTime = realityData.acquisition.endDateTime ? new Date(realityData.acquisition.endDateTime) : undefined; this.acquisition.acquirer = realityData.acquisition.acquirer ? realityData.acquisition.acquirer : undefined; } this.size = realityData.size; this.authoring = realityData.authoring; this.classification = realityData.classification; this.type = realityData.type; this.extent = realityData.extent; // eslint-disable-next-line @typescript-eslint/no-deprecated this.accessControl = realityData.accessControl; this.modifiedDateTime = new Date(realityData.modifiedDateTime); this.lastAccessedDateTime = new Date(realityData.lastAccessedDateTime); this.createdDateTime = new Date(realityData.createdDateTime); } if (iTwinId) this.iTwinId = iTwinId; } /** * Gets string url to fetch blob data from. Access is read-only. * @param accessToken The client request context. * @param blobPath name or path of tile * @param writeAccess Optional boolean indicating if write access is requested. Default is false for read-only access. The realitydata:modify scope is required to grant the "write" access. * @returns string url for blob data * @beta */ async getBlobUrl(accessToken, blobPath, writeAccess = false) { const accessTokenResolved = await this.resolveAccessToken(accessToken); const url = await this.getContainerUrl(accessTokenResolved, writeAccess); if (blobPath === undefined) return url; const host = `${url.origin + url.pathname}/`; const query = url.search; return new URL(`${host}${blobPath}${query}`); } /** * Try to use authorizationClient in RealityDataClientOptions to get the access token * otherwise, will return the input token * This is a workaround to support different authorization client for the reality data client and iTwin-core. */ async resolveAccessToken(accessToken) { return this.client?.authorizationClient ? this.client.authorizationClient.getAccessToken() : accessToken; } /** * Gets a tile access url URL object * @param accessToken The client request context. * @param writeAccess Optional boolean indicating if write access is requested. Default is false for read-only access. * @returns app URL object for blob url * @beta */ async getContainerUrl(accessToken, writeAccess = false) { if (!this.client) throw new BentleyError(422, "Invalid container request (RealityDataAccessClient is not set)."); const access = (writeAccess === true ? "Write" : "Read"); const accessTokenResolved = await this.resolveAccessToken(accessToken); try { const containerCache = this._containerCache.getCache(access); const blobUrlRequiresRefresh = !containerCache?.timeStamp || (Date.now() - containerCache?.timeStamp.getTime()) > 3000000; // 3 million milliseconds or 50 minutes if (undefined === containerCache?.url || blobUrlRequiresRefresh) { const url = new URL(`${this.client.baseUrl}/${this.id}/${writeAccess === true ? "writeAccess" : "readAccess"}`); if (this.iTwinId) url.searchParams.append("iTwinId", this.iTwinId); const requestOptions = getRequestConfig(accessTokenResolved, "GET", url.href, this.client.apiVersion); const response = await axios.get(url.href, requestOptions); if (!response.data) { throw new BentleyError(422, "Invalid container request (API returned an unexpected response)."); } // update cache const newContainerCacheValue = { url: new URL(response.data._links.containerUrl.href), timeStamp: new Date(Date.now()), }; this._containerCache.setCache(newContainerCacheValue, access); } // eslint-disable-next-line @typescript-eslint/no-non-null-assertion return this._containerCache.getCache(access).url; } catch { throw new BentleyError(422, "Invalid container request."); } } } //# sourceMappingURL=RealityData.js.map