mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2024-11-25 15:06:55 +00:00
Refactor Data Access Utility (#112)
This commit is contained in:
parent
6dcdacc8c4
commit
6d142f16f9
@ -20,11 +20,13 @@ import { ContainerRequest } from "@azure/cosmos/dist-esm/client/Container/Contai
|
||||
import { CosmosClient } from "./CosmosClient";
|
||||
import { DatabaseRequest } from "@azure/cosmos/dist-esm/client/Database/DatabaseRequest";
|
||||
import { LocalStorageUtility, StorageKey } from "../Shared/StorageUtility";
|
||||
import { MessageHandler } from "./MessageHandler";
|
||||
import { sendCachedDataMessage, canSendMessage } from "./MessageHandler";
|
||||
import { MessageTypes } from "../Contracts/ExplorerContracts";
|
||||
import { OfferUtils } from "../Utils/OfferUtils";
|
||||
import { RequestOptions } from "@azure/cosmos/dist-esm";
|
||||
import StoredProcedure from "../Explorer/Tree/StoredProcedure";
|
||||
import { Platform, config } from "../Config";
|
||||
import { getAuthorizationHeader } from "../Utils/AuthorizationUtils";
|
||||
|
||||
export function getCommonQueryOptions(options: FeedOptions): any {
|
||||
const storedItemPerPageSetting: number = LocalStorageUtility.getEntryNumber(StorageKey.ActualItemPerPage);
|
||||
@ -43,9 +45,7 @@ export function getCommonQueryOptions(options: FeedOptions): any {
|
||||
return options;
|
||||
}
|
||||
|
||||
// TODO: Add timeout for all promises
|
||||
export abstract class DataAccessUtilityBase {
|
||||
public queryDocuments(
|
||||
export function queryDocuments(
|
||||
databaseId: string,
|
||||
containerId: string,
|
||||
query: string,
|
||||
@ -59,7 +59,7 @@ export abstract class DataAccessUtilityBase {
|
||||
return Q(documentsIterator);
|
||||
}
|
||||
|
||||
public readStoredProcedures(
|
||||
export function readStoredProcedures(
|
||||
collection: ViewModels.Collection,
|
||||
options?: any
|
||||
): Q.Promise<DataModels.StoredProcedure[]> {
|
||||
@ -73,7 +73,7 @@ export abstract class DataAccessUtilityBase {
|
||||
);
|
||||
}
|
||||
|
||||
public readStoredProcedure(
|
||||
export function readStoredProcedure(
|
||||
collection: ViewModels.Collection,
|
||||
requestedResource: DataModels.Resource,
|
||||
options?: any
|
||||
@ -87,7 +87,7 @@ export abstract class DataAccessUtilityBase {
|
||||
.then(response => response.resource as DataModels.StoredProcedure)
|
||||
);
|
||||
}
|
||||
public readUserDefinedFunctions(
|
||||
export function readUserDefinedFunctions(
|
||||
collection: ViewModels.Collection,
|
||||
options: any
|
||||
): Q.Promise<DataModels.UserDefinedFunction[]> {
|
||||
@ -100,7 +100,7 @@ export abstract class DataAccessUtilityBase {
|
||||
.then(response => response.resources as DataModels.UserDefinedFunction[])
|
||||
);
|
||||
}
|
||||
public readUserDefinedFunction(
|
||||
export function readUserDefinedFunction(
|
||||
collection: ViewModels.Collection,
|
||||
requestedResource: DataModels.Resource,
|
||||
options?: any
|
||||
@ -115,7 +115,7 @@ export abstract class DataAccessUtilityBase {
|
||||
);
|
||||
}
|
||||
|
||||
public readTriggers(collection: ViewModels.Collection, options: any): Q.Promise<DataModels.Trigger[]> {
|
||||
export function readTriggers(collection: ViewModels.Collection, options: any): Q.Promise<DataModels.Trigger[]> {
|
||||
return Q(
|
||||
CosmosClient.client()
|
||||
.database(collection.databaseId)
|
||||
@ -126,7 +126,7 @@ export abstract class DataAccessUtilityBase {
|
||||
);
|
||||
}
|
||||
|
||||
public readTrigger(
|
||||
export function readTrigger(
|
||||
collection: ViewModels.Collection,
|
||||
requestedResource: DataModels.Resource,
|
||||
options?: any
|
||||
@ -141,7 +141,7 @@ export abstract class DataAccessUtilityBase {
|
||||
);
|
||||
}
|
||||
|
||||
public executeStoredProcedure(
|
||||
export function executeStoredProcedure(
|
||||
collection: ViewModels.Collection,
|
||||
storedProcedure: StoredProcedure,
|
||||
partitionKeyValue: any,
|
||||
@ -169,7 +169,7 @@ export abstract class DataAccessUtilityBase {
|
||||
);
|
||||
}
|
||||
|
||||
public readDocument(collection: ViewModels.CollectionBase, documentId: ViewModels.DocumentId): Q.Promise<any> {
|
||||
export function readDocument(collection: ViewModels.CollectionBase, documentId: ViewModels.DocumentId): Q.Promise<any> {
|
||||
const partitionKey = documentId.partitionKeyValue;
|
||||
|
||||
return Q(
|
||||
@ -182,14 +182,14 @@ export abstract class DataAccessUtilityBase {
|
||||
);
|
||||
}
|
||||
|
||||
public getPartitionKeyHeaderForConflict(conflictId: ViewModels.ConflictId): Object {
|
||||
export function getPartitionKeyHeaderForConflict(conflictId: ViewModels.ConflictId): Object {
|
||||
const partitionKeyDefinition: DataModels.PartitionKey = conflictId.partitionKey;
|
||||
const partitionKeyValue: any = conflictId.partitionKeyValue;
|
||||
|
||||
return this.getPartitionKeyHeader(partitionKeyDefinition, partitionKeyValue);
|
||||
return getPartitionKeyHeader(partitionKeyDefinition, partitionKeyValue);
|
||||
}
|
||||
|
||||
public getPartitionKeyHeader(partitionKeyDefinition: DataModels.PartitionKey, partitionKeyValue: any): Object {
|
||||
export function getPartitionKeyHeader(partitionKeyDefinition: DataModels.PartitionKey, partitionKeyValue: any): Object {
|
||||
if (!partitionKeyDefinition) {
|
||||
return undefined;
|
||||
}
|
||||
@ -201,7 +201,7 @@ export abstract class DataAccessUtilityBase {
|
||||
return [partitionKeyValue];
|
||||
}
|
||||
|
||||
public updateCollection(
|
||||
export function updateCollection(
|
||||
databaseId: string,
|
||||
collectionId: string,
|
||||
newCollection: DataModels.Collection,
|
||||
@ -213,12 +213,12 @@ export abstract class DataAccessUtilityBase {
|
||||
.container(collectionId)
|
||||
.replace(newCollection as ContainerDefinition, options)
|
||||
.then(async (response: ContainerResponse) => {
|
||||
return this.refreshCachedResources().then(() => response.resource as DataModels.Collection);
|
||||
return refreshCachedResources().then(() => response.resource as DataModels.Collection);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
public updateDocument(
|
||||
export function updateDocument(
|
||||
collection: ViewModels.CollectionBase,
|
||||
documentId: ViewModels.DocumentId,
|
||||
newDocument: any
|
||||
@ -235,7 +235,7 @@ export abstract class DataAccessUtilityBase {
|
||||
);
|
||||
}
|
||||
|
||||
public updateOffer(
|
||||
export function updateOffer(
|
||||
offer: DataModels.Offer,
|
||||
newOffer: DataModels.Offer,
|
||||
options?: RequestOptions
|
||||
@ -245,12 +245,12 @@ export abstract class DataAccessUtilityBase {
|
||||
.offer(offer.id)
|
||||
.replace(newOffer, options)
|
||||
.then(response => {
|
||||
return Promise.all([this.refreshCachedOffers(), this.refreshCachedResources()]).then(() => response.resource);
|
||||
return Promise.all([refreshCachedOffers(), refreshCachedResources()]).then(() => response.resource);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
public updateStoredProcedure(
|
||||
export function updateStoredProcedure(
|
||||
collection: ViewModels.Collection,
|
||||
storedProcedure: DataModels.StoredProcedure,
|
||||
options: any
|
||||
@ -265,7 +265,7 @@ export abstract class DataAccessUtilityBase {
|
||||
);
|
||||
}
|
||||
|
||||
public updateUserDefinedFunction(
|
||||
export function updateUserDefinedFunction(
|
||||
collection: ViewModels.Collection,
|
||||
userDefinedFunction: DataModels.UserDefinedFunction,
|
||||
options?: any
|
||||
@ -280,7 +280,7 @@ export abstract class DataAccessUtilityBase {
|
||||
);
|
||||
}
|
||||
|
||||
public updateTrigger(
|
||||
export function updateTrigger(
|
||||
collection: ViewModels.Collection,
|
||||
trigger: DataModels.Trigger,
|
||||
options?: any
|
||||
@ -295,7 +295,7 @@ export abstract class DataAccessUtilityBase {
|
||||
);
|
||||
}
|
||||
|
||||
public createDocument(collection: ViewModels.CollectionBase, newDocument: any): Q.Promise<any> {
|
||||
export function createDocument(collection: ViewModels.CollectionBase, newDocument: any): Q.Promise<any> {
|
||||
return Q(
|
||||
CosmosClient.client()
|
||||
.database(collection.databaseId)
|
||||
@ -305,7 +305,7 @@ export abstract class DataAccessUtilityBase {
|
||||
);
|
||||
}
|
||||
|
||||
public createStoredProcedure(
|
||||
export function createStoredProcedure(
|
||||
collection: ViewModels.Collection,
|
||||
newStoredProcedure: DataModels.StoredProcedure,
|
||||
options?: any
|
||||
@ -319,7 +319,7 @@ export abstract class DataAccessUtilityBase {
|
||||
);
|
||||
}
|
||||
|
||||
public createUserDefinedFunction(
|
||||
export function createUserDefinedFunction(
|
||||
collection: ViewModels.Collection,
|
||||
newUserDefinedFunction: DataModels.UserDefinedFunction,
|
||||
options: any
|
||||
@ -333,7 +333,7 @@ export abstract class DataAccessUtilityBase {
|
||||
);
|
||||
}
|
||||
|
||||
public createTrigger(
|
||||
export function createTrigger(
|
||||
collection: ViewModels.Collection,
|
||||
newTrigger: DataModels.Trigger,
|
||||
options?: any
|
||||
@ -347,7 +347,10 @@ export abstract class DataAccessUtilityBase {
|
||||
);
|
||||
}
|
||||
|
||||
public deleteDocument(collection: ViewModels.CollectionBase, documentId: ViewModels.DocumentId): Q.Promise<any> {
|
||||
export function deleteDocument(
|
||||
collection: ViewModels.CollectionBase,
|
||||
documentId: ViewModels.DocumentId
|
||||
): Q.Promise<any> {
|
||||
const partitionKey = documentId.partitionKeyValue;
|
||||
|
||||
return Q(
|
||||
@ -359,12 +362,12 @@ export abstract class DataAccessUtilityBase {
|
||||
);
|
||||
}
|
||||
|
||||
public deleteConflict(
|
||||
export function deleteConflict(
|
||||
collection: ViewModels.CollectionBase,
|
||||
conflictId: ViewModels.ConflictId,
|
||||
options: any = {}
|
||||
): Q.Promise<any> {
|
||||
options.partitionKey = options.partitionKey || this.getPartitionKeyHeaderForConflict(conflictId);
|
||||
options.partitionKey = options.partitionKey || getPartitionKeyHeaderForConflict(conflictId);
|
||||
|
||||
return Q(
|
||||
CosmosClient.client()
|
||||
@ -375,26 +378,26 @@ export abstract class DataAccessUtilityBase {
|
||||
);
|
||||
}
|
||||
|
||||
public deleteCollection(collection: ViewModels.Collection, options: any): Q.Promise<any> {
|
||||
export function deleteCollection(collection: ViewModels.Collection, options: any): Q.Promise<any> {
|
||||
return Q(
|
||||
CosmosClient.client()
|
||||
.database(collection.databaseId)
|
||||
.container(collection.id())
|
||||
.delete()
|
||||
.then(() => this.refreshCachedResources())
|
||||
.then(() => refreshCachedResources())
|
||||
);
|
||||
}
|
||||
|
||||
public deleteDatabase(database: ViewModels.Database, options: any): Q.Promise<any> {
|
||||
export function deleteDatabase(database: ViewModels.Database, options: any): Q.Promise<any> {
|
||||
return Q(
|
||||
CosmosClient.client()
|
||||
.database(database.id())
|
||||
.delete()
|
||||
.then(() => this.refreshCachedResources())
|
||||
.then(() => refreshCachedResources())
|
||||
);
|
||||
}
|
||||
|
||||
public deleteStoredProcedure(
|
||||
export function deleteStoredProcedure(
|
||||
collection: ViewModels.Collection,
|
||||
storedProcedure: DataModels.StoredProcedure,
|
||||
options: any
|
||||
@ -408,7 +411,7 @@ export abstract class DataAccessUtilityBase {
|
||||
);
|
||||
}
|
||||
|
||||
public deleteUserDefinedFunction(
|
||||
export function deleteUserDefinedFunction(
|
||||
collection: ViewModels.Collection,
|
||||
userDefinedFunction: DataModels.UserDefinedFunction,
|
||||
options: any
|
||||
@ -422,7 +425,11 @@ export abstract class DataAccessUtilityBase {
|
||||
);
|
||||
}
|
||||
|
||||
public deleteTrigger(collection: ViewModels.Collection, trigger: DataModels.Trigger, options: any): Q.Promise<any> {
|
||||
export function deleteTrigger(
|
||||
collection: ViewModels.Collection,
|
||||
trigger: DataModels.Trigger,
|
||||
options: any
|
||||
): Q.Promise<any> {
|
||||
return Q(
|
||||
CosmosClient.client()
|
||||
.database(collection.databaseId)
|
||||
@ -432,7 +439,7 @@ export abstract class DataAccessUtilityBase {
|
||||
);
|
||||
}
|
||||
|
||||
public readCollections(database: ViewModels.Database, options: any): Q.Promise<DataModels.Collection[]> {
|
||||
export function readCollections(database: ViewModels.Database, options: any): Q.Promise<DataModels.Collection[]> {
|
||||
return Q(
|
||||
CosmosClient.client()
|
||||
.database(database.id())
|
||||
@ -442,7 +449,7 @@ export abstract class DataAccessUtilityBase {
|
||||
);
|
||||
}
|
||||
|
||||
public readCollection(databaseId: string, collectionId: string): Q.Promise<DataModels.Collection> {
|
||||
export function readCollection(databaseId: string, collectionId: string): Q.Promise<DataModels.Collection> {
|
||||
return Q(
|
||||
CosmosClient.client()
|
||||
.database(databaseId)
|
||||
@ -452,7 +459,7 @@ export abstract class DataAccessUtilityBase {
|
||||
);
|
||||
}
|
||||
|
||||
public readCollectionQuotaInfo(
|
||||
export function readCollectionQuotaInfo(
|
||||
collection: ViewModels.Collection,
|
||||
options: any
|
||||
): Q.Promise<DataModels.CollectionQuotaInfo> {
|
||||
@ -487,7 +494,17 @@ export abstract class DataAccessUtilityBase {
|
||||
);
|
||||
}
|
||||
|
||||
public readOffers(options: any): Q.Promise<DataModels.Offer[]> {
|
||||
export function readOffers(options: any): Q.Promise<DataModels.Offer[]> {
|
||||
try {
|
||||
if (config.platform === Platform.Portal) {
|
||||
return sendCachedDataMessage<DataModels.Offer[]>(MessageTypes.AllOffers, [
|
||||
(<any>window).dataExplorer.databaseAccount().id,
|
||||
Constants.ClientDefaults.portalCacheTimeoutMs
|
||||
]);
|
||||
}
|
||||
} catch (error) {
|
||||
// If error getting cached Offers, continue on and read via SDK
|
||||
}
|
||||
return Q(
|
||||
CosmosClient.client()
|
||||
.offers.readAll()
|
||||
@ -496,7 +513,7 @@ export abstract class DataAccessUtilityBase {
|
||||
);
|
||||
}
|
||||
|
||||
public readOffer(requestedResource: DataModels.Offer, options: any): Q.Promise<DataModels.OfferWithHeaders> {
|
||||
export function readOffer(requestedResource: DataModels.Offer, options: any): Q.Promise<DataModels.OfferWithHeaders> {
|
||||
options = options || {};
|
||||
options.initialHeaders = options.initialHeaders || {};
|
||||
if (!OfferUtils.isOfferV1(requestedResource)) {
|
||||
@ -511,7 +528,18 @@ export abstract class DataAccessUtilityBase {
|
||||
);
|
||||
}
|
||||
|
||||
public readDatabases(options: any): Q.Promise<DataModels.Database[]> {
|
||||
export function readDatabases(options: any): Q.Promise<DataModels.Database[]> {
|
||||
try {
|
||||
if (config.platform === Platform.Portal) {
|
||||
return sendCachedDataMessage<DataModels.Database[]>(MessageTypes.AllDatabases, [
|
||||
(<any>window).dataExplorer.databaseAccount().id,
|
||||
Constants.ClientDefaults.portalCacheTimeoutMs
|
||||
]);
|
||||
}
|
||||
} catch (error) {
|
||||
// If error getting cached DBs, continue on and read via SDK
|
||||
}
|
||||
|
||||
return Q(
|
||||
CosmosClient.client()
|
||||
.databases.readAll()
|
||||
@ -520,7 +548,7 @@ export abstract class DataAccessUtilityBase {
|
||||
);
|
||||
}
|
||||
|
||||
public getOrCreateDatabaseAndCollection(
|
||||
export function getOrCreateDatabaseAndCollection(
|
||||
request: DataModels.CreateDatabaseAndCollectionRequest,
|
||||
options: any
|
||||
): Q.Promise<DataModels.Collection> {
|
||||
@ -579,16 +607,19 @@ export abstract class DataAccessUtilityBase {
|
||||
);
|
||||
})
|
||||
.then(containerResponse => containerResponse.resource as DataModels.Collection)
|
||||
.finally(() => this.refreshCachedResources(options))
|
||||
.finally(() => refreshCachedResources(options))
|
||||
);
|
||||
}
|
||||
|
||||
public createDatabase(request: DataModels.CreateDatabaseRequest, options: any): Q.Promise<DataModels.Database> {
|
||||
export function createDatabase(
|
||||
request: DataModels.CreateDatabaseRequest,
|
||||
options: any
|
||||
): Q.Promise<DataModels.Database> {
|
||||
var deferred = Q.defer<DataModels.Database>();
|
||||
|
||||
this._createDatabase(request, options).then(
|
||||
_createDatabase(request, options).then(
|
||||
(createdDatabase: DataModels.Database) => {
|
||||
this.refreshCachedOffers().then(() => {
|
||||
refreshCachedOffers().then(() => {
|
||||
deferred.resolve(createdDatabase);
|
||||
});
|
||||
},
|
||||
@ -600,23 +631,23 @@ export abstract class DataAccessUtilityBase {
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
public refreshCachedOffers(): Q.Promise<void> {
|
||||
if (MessageHandler.canSendMessage()) {
|
||||
return MessageHandler.sendCachedDataMessage(MessageTypes.RefreshOffers, []);
|
||||
export function refreshCachedOffers(): Q.Promise<void> {
|
||||
if (canSendMessage()) {
|
||||
return sendCachedDataMessage(MessageTypes.RefreshOffers, []);
|
||||
} else {
|
||||
return Q();
|
||||
}
|
||||
}
|
||||
|
||||
public refreshCachedResources(options?: any): Q.Promise<void> {
|
||||
if (MessageHandler.canSendMessage()) {
|
||||
return MessageHandler.sendCachedDataMessage(MessageTypes.RefreshResources, []);
|
||||
export function refreshCachedResources(options?: any): Q.Promise<void> {
|
||||
if (canSendMessage()) {
|
||||
return sendCachedDataMessage(MessageTypes.RefreshResources, []);
|
||||
} else {
|
||||
return Q();
|
||||
}
|
||||
}
|
||||
|
||||
public queryConflicts(
|
||||
export function queryConflicts(
|
||||
databaseId: string,
|
||||
containerId: string,
|
||||
query: string,
|
||||
@ -629,17 +660,30 @@ export abstract class DataAccessUtilityBase {
|
||||
return Q(documentsIterator);
|
||||
}
|
||||
|
||||
public updateOfferThroughputBeyondLimit(
|
||||
request: DataModels.UpdateOfferThroughputRequest,
|
||||
options: any
|
||||
): Q.Promise<void> {
|
||||
export async function updateOfferThroughputBeyondLimit(
|
||||
request: DataModels.UpdateOfferThroughputRequest
|
||||
): Promise<void> {
|
||||
if (config.platform !== Platform.Portal) {
|
||||
throw new Error("Updating throughput beyond specified limit is not supported on this platform");
|
||||
}
|
||||
|
||||
private _createDatabase(
|
||||
request: DataModels.CreateDatabaseRequest,
|
||||
options: any = {}
|
||||
): Q.Promise<DataModels.Database> {
|
||||
const explorer = window.dataExplorer;
|
||||
const url = `${explorer.extensionEndpoint()}/api/offerthroughputrequest/updatebeyondspecifiedlimit`;
|
||||
const authorizationHeader = getAuthorizationHeader();
|
||||
|
||||
const response = await fetch(url, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(request),
|
||||
headers: { [authorizationHeader.header]: authorizationHeader.token }
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
return undefined;
|
||||
}
|
||||
throw new Error(await response.text());
|
||||
}
|
||||
|
||||
function _createDatabase(request: DataModels.CreateDatabaseRequest, options: any = {}): Q.Promise<DataModels.Database> {
|
||||
const { databaseId, databaseLevelThroughput, offerThroughput, autoPilot, hasAutoPilotV2FeatureFlag } = request;
|
||||
const createBody: DatabaseRequest = { id: databaseId };
|
||||
const databaseOptions: any = options && _.omit(options, "sharedOfferThroughput");
|
||||
@ -664,8 +708,7 @@ export abstract class DataAccessUtilityBase {
|
||||
CosmosClient.client()
|
||||
.databases.create(createBody, databaseOptions)
|
||||
.then((response: DatabaseResponse) => {
|
||||
return this.refreshCachedResources(databaseOptions).then(() => response.resource);
|
||||
return refreshCachedResources(databaseOptions).then(() => response.resource);
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -5,9 +5,9 @@ import * as ViewModels from "../Contracts/ViewModels";
|
||||
import Q from "q";
|
||||
import { ConflictDefinition, ItemDefinition, QueryIterator, Resource } from "@azure/cosmos";
|
||||
import { ConsoleDataType } from "../Explorer/Menus/NotificationConsole/NotificationConsoleComponent";
|
||||
import { DataAccessUtilityBase } from "./DataAccessUtilityBase";
|
||||
import * as DataAccessUtilityBase from "./DataAccessUtilityBase";
|
||||
import * as Logger from "./Logger";
|
||||
import { MessageHandler } from "./MessageHandler";
|
||||
import { sendMessage } from "./MessageHandler";
|
||||
import { MessageTypes } from "../Contracts/ExplorerContracts";
|
||||
import { MinimalQueryIterator, nextPage } from "./IteratorUtilities";
|
||||
import { NotificationConsoleUtils } from "../Utils/NotificationConsoleUtils";
|
||||
@ -16,15 +16,13 @@ import StoredProcedure from "../Explorer/Tree/StoredProcedure";
|
||||
|
||||
// TODO: Log all promise resolutions and errors with verbosity levels
|
||||
export default class DocumentClientUtilityBase {
|
||||
constructor(private _dataAccessUtility: DataAccessUtilityBase) {}
|
||||
|
||||
public queryDocuments(
|
||||
databaseId: string,
|
||||
containerId: string,
|
||||
query: string,
|
||||
options: any
|
||||
): Q.Promise<QueryIterator<ItemDefinition & Resource>> {
|
||||
return this._dataAccessUtility.queryDocuments(databaseId, containerId, query, options);
|
||||
return DataAccessUtilityBase.queryDocuments(databaseId, containerId, query, options);
|
||||
}
|
||||
|
||||
public queryConflicts(
|
||||
@ -33,7 +31,7 @@ export default class DocumentClientUtilityBase {
|
||||
query: string,
|
||||
options: any
|
||||
): Q.Promise<QueryIterator<ConflictDefinition & Resource>> {
|
||||
return this._dataAccessUtility.queryConflicts(databaseId, containerId, query, options);
|
||||
return DataAccessUtilityBase.queryConflicts(databaseId, containerId, query, options);
|
||||
}
|
||||
|
||||
public getEntityName() {
|
||||
@ -54,8 +52,7 @@ export default class DocumentClientUtilityBase {
|
||||
ConsoleDataType.InProgress,
|
||||
`Querying stored procedures for container ${collection.id()}`
|
||||
);
|
||||
this._dataAccessUtility
|
||||
.readStoredProcedures(collection, options)
|
||||
DataAccessUtilityBase.readStoredProcedures(collection, options)
|
||||
.then(
|
||||
(storedProcedures: DataModels.StoredProcedure[]) => {
|
||||
deferred.resolve(storedProcedures);
|
||||
@ -82,7 +79,7 @@ export default class DocumentClientUtilityBase {
|
||||
requestedResource: DataModels.Resource,
|
||||
options?: any
|
||||
): Q.Promise<DataModels.StoredProcedure> {
|
||||
return this._dataAccessUtility.readStoredProcedure(collection, requestedResource, options);
|
||||
return DataAccessUtilityBase.readStoredProcedure(collection, requestedResource, options);
|
||||
}
|
||||
|
||||
public readUserDefinedFunctions(
|
||||
@ -94,8 +91,7 @@ export default class DocumentClientUtilityBase {
|
||||
ConsoleDataType.InProgress,
|
||||
`Querying user defined functions for collection ${collection.id()}`
|
||||
);
|
||||
this._dataAccessUtility
|
||||
.readUserDefinedFunctions(collection, options)
|
||||
DataAccessUtilityBase.readUserDefinedFunctions(collection, options)
|
||||
.then(
|
||||
(userDefinedFunctions: DataModels.UserDefinedFunction[]) => {
|
||||
deferred.resolve(userDefinedFunctions);
|
||||
@ -122,7 +118,7 @@ export default class DocumentClientUtilityBase {
|
||||
requestedResource: DataModels.Resource,
|
||||
options: any
|
||||
): Q.Promise<DataModels.UserDefinedFunction> {
|
||||
return this._dataAccessUtility.readUserDefinedFunction(collection, requestedResource, options);
|
||||
return DataAccessUtilityBase.readUserDefinedFunction(collection, requestedResource, options);
|
||||
}
|
||||
|
||||
public readTriggers(collection: ViewModels.Collection, options: any): Q.Promise<DataModels.Trigger[]> {
|
||||
@ -132,8 +128,7 @@ export default class DocumentClientUtilityBase {
|
||||
ConsoleDataType.InProgress,
|
||||
`Querying triggers for container ${collection.id()}`
|
||||
);
|
||||
this._dataAccessUtility
|
||||
.readTriggers(collection, options)
|
||||
DataAccessUtilityBase.readTriggers(collection, options)
|
||||
.then(
|
||||
(triggers: DataModels.Trigger[]) => {
|
||||
deferred.resolve(triggers);
|
||||
@ -160,7 +155,7 @@ export default class DocumentClientUtilityBase {
|
||||
requestedResource: DataModels.Resource,
|
||||
options?: any
|
||||
): Q.Promise<DataModels.Trigger> {
|
||||
return this._dataAccessUtility.readTrigger(collection, requestedResource, options);
|
||||
return DataAccessUtilityBase.readTrigger(collection, requestedResource, options);
|
||||
}
|
||||
|
||||
public executeStoredProcedure(
|
||||
@ -175,8 +170,7 @@ export default class DocumentClientUtilityBase {
|
||||
ConsoleDataType.InProgress,
|
||||
`Executing stored procedure ${storedProcedure.id()}`
|
||||
);
|
||||
this._dataAccessUtility
|
||||
.executeStoredProcedure(collection, storedProcedure, partitionKeyValue, params)
|
||||
DataAccessUtilityBase.executeStoredProcedure(collection, storedProcedure, partitionKeyValue, params)
|
||||
.then(
|
||||
(response: any) => {
|
||||
deferred.resolve(response);
|
||||
@ -250,8 +244,7 @@ export default class DocumentClientUtilityBase {
|
||||
ConsoleDataType.InProgress,
|
||||
`Reading ${entityName} ${documentId.id()}`
|
||||
);
|
||||
this._dataAccessUtility
|
||||
.readDocument(collection, documentId)
|
||||
DataAccessUtilityBase.readDocument(collection, documentId)
|
||||
.then(
|
||||
(document: any) => {
|
||||
deferred.resolve(document);
|
||||
@ -283,8 +276,7 @@ export default class DocumentClientUtilityBase {
|
||||
ConsoleDataType.InProgress,
|
||||
`Updating container ${collection.id()}`
|
||||
);
|
||||
this._dataAccessUtility
|
||||
.updateCollection(databaseId, collection.id(), newCollection)
|
||||
DataAccessUtilityBase.updateCollection(databaseId, collection.id(), newCollection)
|
||||
.then(
|
||||
(replacedCollection: DataModels.Collection) => {
|
||||
NotificationConsoleUtils.logConsoleMessage(
|
||||
@ -321,8 +313,7 @@ export default class DocumentClientUtilityBase {
|
||||
ConsoleDataType.InProgress,
|
||||
`Updating ${entityName} ${documentId.id()}`
|
||||
);
|
||||
this._dataAccessUtility
|
||||
.updateDocument(collection, documentId, newDocument)
|
||||
DataAccessUtilityBase.updateDocument(collection, documentId, newDocument)
|
||||
.then(
|
||||
(updatedDocument: any) => {
|
||||
NotificationConsoleUtils.logConsoleMessage(
|
||||
@ -358,8 +349,7 @@ export default class DocumentClientUtilityBase {
|
||||
ConsoleDataType.InProgress,
|
||||
`Updating offer for resource ${offer.resource}`
|
||||
);
|
||||
this._dataAccessUtility
|
||||
.updateOffer(offer, newOffer, options)
|
||||
DataAccessUtilityBase.updateOffer(offer, newOffer, options)
|
||||
.then(
|
||||
(replacedOffer: DataModels.Offer) => {
|
||||
NotificationConsoleUtils.logConsoleMessage(
|
||||
@ -393,10 +383,7 @@ export default class DocumentClientUtilityBase {
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
public updateOfferThroughputBeyondLimit(
|
||||
requestPayload: DataModels.UpdateOfferThroughputRequest,
|
||||
options: any = {}
|
||||
): Q.Promise<void> {
|
||||
public updateOfferThroughputBeyondLimit(requestPayload: DataModels.UpdateOfferThroughputRequest): Q.Promise<void> {
|
||||
const deferred: Q.Deferred<void> = Q.defer<void>();
|
||||
const resourceDescriptionInfo: string = requestPayload.collectionName
|
||||
? `database ${requestPayload.databaseName} and container ${requestPayload.collectionName}`
|
||||
@ -405,8 +392,7 @@ export default class DocumentClientUtilityBase {
|
||||
ConsoleDataType.InProgress,
|
||||
`Requesting increase in throughput to ${requestPayload.throughput} for ${resourceDescriptionInfo}`
|
||||
);
|
||||
this._dataAccessUtility
|
||||
.updateOfferThroughputBeyondLimit(requestPayload, options)
|
||||
DataAccessUtilityBase.updateOfferThroughputBeyondLimit(requestPayload)
|
||||
.then(
|
||||
() => {
|
||||
NotificationConsoleUtils.logConsoleMessage(
|
||||
@ -439,8 +425,7 @@ export default class DocumentClientUtilityBase {
|
||||
ConsoleDataType.InProgress,
|
||||
`Updating stored procedure ${storedProcedure.id}`
|
||||
);
|
||||
this._dataAccessUtility
|
||||
.updateStoredProcedure(collection, storedProcedure, options)
|
||||
DataAccessUtilityBase.updateStoredProcedure(collection, storedProcedure, options)
|
||||
.then(
|
||||
(updatedStoredProcedure: DataModels.StoredProcedure) => {
|
||||
NotificationConsoleUtils.logConsoleMessage(
|
||||
@ -476,8 +461,7 @@ export default class DocumentClientUtilityBase {
|
||||
ConsoleDataType.InProgress,
|
||||
`Updating user defined function ${userDefinedFunction.id}`
|
||||
);
|
||||
this._dataAccessUtility
|
||||
.updateUserDefinedFunction(collection, userDefinedFunction, options)
|
||||
DataAccessUtilityBase.updateUserDefinedFunction(collection, userDefinedFunction, options)
|
||||
.then(
|
||||
(updatedUserDefinedFunction: DataModels.UserDefinedFunction) => {
|
||||
NotificationConsoleUtils.logConsoleMessage(
|
||||
@ -506,8 +490,7 @@ export default class DocumentClientUtilityBase {
|
||||
public updateTrigger(collection: ViewModels.Collection, trigger: DataModels.Trigger): Q.Promise<DataModels.Trigger> {
|
||||
var deferred = Q.defer<any>();
|
||||
const id = NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.InProgress, `Updating trigger ${trigger.id}`);
|
||||
this._dataAccessUtility
|
||||
.updateTrigger(collection, trigger)
|
||||
DataAccessUtilityBase.updateTrigger(collection, trigger)
|
||||
.then(
|
||||
(updatedTrigger: DataModels.Trigger) => {
|
||||
NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.Info, `Updated trigger ${trigger.id}`);
|
||||
@ -537,8 +520,7 @@ export default class DocumentClientUtilityBase {
|
||||
ConsoleDataType.InProgress,
|
||||
`Creating new ${entityName} for container ${collection.id()}`
|
||||
);
|
||||
this._dataAccessUtility
|
||||
.createDocument(collection, newDocument)
|
||||
DataAccessUtilityBase.createDocument(collection, newDocument)
|
||||
.then(
|
||||
(savedDocument: any) => {
|
||||
NotificationConsoleUtils.logConsoleMessage(
|
||||
@ -574,8 +556,7 @@ export default class DocumentClientUtilityBase {
|
||||
ConsoleDataType.InProgress,
|
||||
`Creating stored procedure for container ${collection.id()}`
|
||||
);
|
||||
this._dataAccessUtility
|
||||
.createStoredProcedure(collection, newStoredProcedure, options)
|
||||
DataAccessUtilityBase.createStoredProcedure(collection, newStoredProcedure, options)
|
||||
.then(
|
||||
(createdStoredProcedure: DataModels.StoredProcedure) => {
|
||||
NotificationConsoleUtils.logConsoleMessage(
|
||||
@ -611,8 +592,7 @@ export default class DocumentClientUtilityBase {
|
||||
ConsoleDataType.InProgress,
|
||||
`Creating user defined function for container ${collection.id()}`
|
||||
);
|
||||
this._dataAccessUtility
|
||||
.createUserDefinedFunction(collection, newUserDefinedFunction, options)
|
||||
DataAccessUtilityBase.createUserDefinedFunction(collection, newUserDefinedFunction, options)
|
||||
.then(
|
||||
(createdUserDefinedFunction: DataModels.UserDefinedFunction) => {
|
||||
NotificationConsoleUtils.logConsoleMessage(
|
||||
@ -648,8 +628,7 @@ export default class DocumentClientUtilityBase {
|
||||
ConsoleDataType.InProgress,
|
||||
`Creating trigger for container ${collection.id()}`
|
||||
);
|
||||
this._dataAccessUtility
|
||||
.createTrigger(collection, newTrigger, options)
|
||||
DataAccessUtilityBase.createTrigger(collection, newTrigger, options)
|
||||
.then(
|
||||
(createdTrigger: DataModels.Trigger) => {
|
||||
NotificationConsoleUtils.logConsoleMessage(
|
||||
@ -682,8 +661,7 @@ export default class DocumentClientUtilityBase {
|
||||
ConsoleDataType.InProgress,
|
||||
`Deleting ${entityName} ${documentId.id()}`
|
||||
);
|
||||
this._dataAccessUtility
|
||||
.deleteDocument(collection, documentId)
|
||||
DataAccessUtilityBase.deleteDocument(collection, documentId)
|
||||
.then(
|
||||
(response: any) => {
|
||||
NotificationConsoleUtils.logConsoleMessage(
|
||||
@ -720,8 +698,7 @@ export default class DocumentClientUtilityBase {
|
||||
ConsoleDataType.InProgress,
|
||||
`Deleting conflict ${conflictId.id()}`
|
||||
);
|
||||
this._dataAccessUtility
|
||||
.deleteConflict(collection, conflictId, options)
|
||||
DataAccessUtilityBase.deleteConflict(collection, conflictId, options)
|
||||
.then(
|
||||
(response: any) => {
|
||||
NotificationConsoleUtils.logConsoleMessage(
|
||||
@ -754,8 +731,7 @@ export default class DocumentClientUtilityBase {
|
||||
ConsoleDataType.InProgress,
|
||||
`Deleting container ${collection.id()}`
|
||||
);
|
||||
this._dataAccessUtility
|
||||
.deleteCollection(collection, options)
|
||||
DataAccessUtilityBase.deleteCollection(collection, options)
|
||||
.then(
|
||||
(response: any) => {
|
||||
NotificationConsoleUtils.logConsoleMessage(
|
||||
@ -788,8 +764,7 @@ export default class DocumentClientUtilityBase {
|
||||
ConsoleDataType.InProgress,
|
||||
`Deleting database ${database.id()}`
|
||||
);
|
||||
this._dataAccessUtility
|
||||
.deleteDatabase(database, options)
|
||||
DataAccessUtilityBase.deleteDatabase(database, options)
|
||||
.then(
|
||||
(response: any) => {
|
||||
NotificationConsoleUtils.logConsoleMessage(
|
||||
@ -826,8 +801,7 @@ export default class DocumentClientUtilityBase {
|
||||
ConsoleDataType.InProgress,
|
||||
`Deleting stored procedure ${storedProcedure.id}`
|
||||
);
|
||||
this._dataAccessUtility
|
||||
.deleteStoredProcedure(collection, storedProcedure, options)
|
||||
DataAccessUtilityBase.deleteStoredProcedure(collection, storedProcedure, options)
|
||||
.then(
|
||||
(response: any) => {
|
||||
NotificationConsoleUtils.logConsoleMessage(
|
||||
@ -863,8 +837,7 @@ export default class DocumentClientUtilityBase {
|
||||
ConsoleDataType.InProgress,
|
||||
`Deleting user defined function ${userDefinedFunction.id}`
|
||||
);
|
||||
this._dataAccessUtility
|
||||
.deleteUserDefinedFunction(collection, userDefinedFunction, options)
|
||||
DataAccessUtilityBase.deleteUserDefinedFunction(collection, userDefinedFunction, options)
|
||||
.then(
|
||||
(response: any) => {
|
||||
NotificationConsoleUtils.logConsoleMessage(
|
||||
@ -897,8 +870,7 @@ export default class DocumentClientUtilityBase {
|
||||
): Q.Promise<DataModels.Trigger> {
|
||||
var deferred = Q.defer<any>();
|
||||
const id = NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.InProgress, `Deleting trigger ${trigger.id}`);
|
||||
this._dataAccessUtility
|
||||
.deleteTrigger(collection, trigger, options)
|
||||
DataAccessUtilityBase.deleteTrigger(collection, trigger, options)
|
||||
.then(
|
||||
(response: any) => {
|
||||
NotificationConsoleUtils.logConsoleMessage(
|
||||
@ -925,11 +897,11 @@ export default class DocumentClientUtilityBase {
|
||||
}
|
||||
|
||||
public refreshCachedResources(options: any = {}): Q.Promise<void> {
|
||||
return this._dataAccessUtility.refreshCachedResources(options);
|
||||
return DataAccessUtilityBase.refreshCachedResources(options);
|
||||
}
|
||||
|
||||
public refreshCachedOffers(): Q.Promise<void> {
|
||||
return this._dataAccessUtility.refreshCachedOffers();
|
||||
return DataAccessUtilityBase.refreshCachedOffers();
|
||||
}
|
||||
|
||||
public readCollections(database: ViewModels.Database, options: any = {}): Q.Promise<DataModels.Collection[]> {
|
||||
@ -938,8 +910,7 @@ export default class DocumentClientUtilityBase {
|
||||
ConsoleDataType.InProgress,
|
||||
`Querying containers for database ${database.id()}`
|
||||
);
|
||||
this._dataAccessUtility
|
||||
.readCollections(database, options)
|
||||
DataAccessUtilityBase.readCollections(database, options)
|
||||
.then(
|
||||
(collections: DataModels.Collection[]) => {
|
||||
deferred.resolve(collections);
|
||||
@ -968,8 +939,7 @@ export default class DocumentClientUtilityBase {
|
||||
`Querying container ${collectionId}`
|
||||
);
|
||||
|
||||
this._dataAccessUtility
|
||||
.readCollection(databaseId, collectionId)
|
||||
DataAccessUtilityBase.readCollection(databaseId, collectionId)
|
||||
.then(
|
||||
(collection: DataModels.Collection) => {
|
||||
deferred.resolve(collection);
|
||||
@ -1001,8 +971,7 @@ export default class DocumentClientUtilityBase {
|
||||
ConsoleDataType.InProgress,
|
||||
`Querying quota info for container ${collection.id}`
|
||||
);
|
||||
this._dataAccessUtility
|
||||
.readCollectionQuotaInfo(collection, options)
|
||||
DataAccessUtilityBase.readCollectionQuotaInfo(collection, options)
|
||||
.then(
|
||||
(quota: DataModels.CollectionQuotaInfo) => {
|
||||
deferred.resolve(quota);
|
||||
@ -1028,8 +997,7 @@ export default class DocumentClientUtilityBase {
|
||||
var deferred = Q.defer<DataModels.Offer[]>();
|
||||
|
||||
const id = NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.InProgress, "Querying offers");
|
||||
this._dataAccessUtility
|
||||
.readOffers(options)
|
||||
DataAccessUtilityBase.readOffers(options)
|
||||
.then(
|
||||
(offers: DataModels.Offer[]) => {
|
||||
deferred.resolve(offers);
|
||||
@ -1055,8 +1023,7 @@ export default class DocumentClientUtilityBase {
|
||||
var deferred = Q.defer<DataModels.OfferWithHeaders>();
|
||||
|
||||
const id = NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.InProgress, "Querying offer");
|
||||
this._dataAccessUtility
|
||||
.readOffer(requestedResource, options)
|
||||
DataAccessUtilityBase.readOffer(requestedResource, options)
|
||||
.then(
|
||||
(offer: DataModels.OfferWithHeaders) => {
|
||||
deferred.resolve(offer);
|
||||
@ -1081,8 +1048,7 @@ export default class DocumentClientUtilityBase {
|
||||
public readDatabases(options: any): Q.Promise<DataModels.Database[]> {
|
||||
var deferred = Q.defer<any>();
|
||||
const id = NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.InProgress, "Querying databases");
|
||||
this._dataAccessUtility
|
||||
.readDatabases(options)
|
||||
DataAccessUtilityBase.readDatabases(options)
|
||||
.then(
|
||||
(databases: DataModels.Database[]) => {
|
||||
deferred.resolve(databases);
|
||||
@ -1114,8 +1080,7 @@ export default class DocumentClientUtilityBase {
|
||||
`Creating a new container ${request.collectionId} for database ${request.databaseId}`
|
||||
);
|
||||
|
||||
this._dataAccessUtility
|
||||
.getOrCreateDatabaseAndCollection(request, options)
|
||||
DataAccessUtilityBase.getOrCreateDatabaseAndCollection(request, options)
|
||||
.then(
|
||||
(collection: DataModels.Collection) => {
|
||||
NotificationConsoleUtils.logConsoleMessage(
|
||||
@ -1146,8 +1111,7 @@ export default class DocumentClientUtilityBase {
|
||||
`Creating a new database ${request.databaseId}`
|
||||
);
|
||||
|
||||
this._dataAccessUtility
|
||||
.createDatabase(request, options)
|
||||
DataAccessUtilityBase.createDatabase(request, options)
|
||||
.then(
|
||||
(database: DataModels.Database) => {
|
||||
NotificationConsoleUtils.logConsoleMessage(
|
||||
@ -1175,7 +1139,7 @@ export default class DocumentClientUtilityBase {
|
||||
if (error.message && error.message.toLowerCase().indexOf("sharedoffer is disabled for your account") > 0) {
|
||||
return;
|
||||
}
|
||||
MessageHandler.sendMessage({
|
||||
sendMessage({
|
||||
type: MessageTypes.ForbiddenError,
|
||||
reason: error && error.message ? error.message : error
|
||||
});
|
||||
|
@ -1,46 +1,26 @@
|
||||
jest.mock("./MessageHandler");
|
||||
import { LogEntryLevel } from "../Contracts/Diagnostics";
|
||||
import * as Logger from "./Logger";
|
||||
import { MessageHandler } from "./MessageHandler";
|
||||
import { MessageTypes } from "../Contracts/ExplorerContracts";
|
||||
import { sendMessage } from "./MessageHandler";
|
||||
|
||||
describe("Logger", () => {
|
||||
let sendMessageSpy: jasmine.Spy;
|
||||
|
||||
beforeEach(() => {
|
||||
sendMessageSpy = spyOn(MessageHandler, "sendMessage");
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
sendMessageSpy = null;
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
|
||||
it("should log info messages", () => {
|
||||
Logger.logInfo("Test info", "DocDB");
|
||||
const spyArgs = sendMessageSpy.calls.mostRecent().args[0];
|
||||
|
||||
expect(spyArgs.type).toBe(MessageTypes.LogInfo);
|
||||
expect(spyArgs.data).toContain(LogEntryLevel.Verbose);
|
||||
expect(spyArgs.data).toContain("DocDB");
|
||||
expect(spyArgs.data).toContain("Test info");
|
||||
expect(sendMessage).toBeCalled();
|
||||
});
|
||||
|
||||
it("should log error messages", () => {
|
||||
Logger.logError("Test error", "DocDB");
|
||||
const spyArgs = sendMessageSpy.calls.mostRecent().args[0];
|
||||
|
||||
expect(spyArgs.type).toBe(MessageTypes.LogInfo);
|
||||
expect(spyArgs.data).toContain(LogEntryLevel.Error);
|
||||
expect(spyArgs.data).toContain("DocDB");
|
||||
expect(spyArgs.data).toContain("Test error");
|
||||
expect(sendMessage).toBeCalled();
|
||||
});
|
||||
|
||||
it("should log warnings", () => {
|
||||
Logger.logWarning("Test warning", "DocDB");
|
||||
const spyArgs = sendMessageSpy.calls.mostRecent().args[0];
|
||||
|
||||
expect(spyArgs.type).toBe(MessageTypes.LogInfo);
|
||||
expect(spyArgs.data).toContain(LogEntryLevel.Warning);
|
||||
expect(spyArgs.data).toContain("DocDB");
|
||||
expect(spyArgs.data).toContain("Test warning");
|
||||
expect(sendMessage).toBeCalled();
|
||||
});
|
||||
});
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { MessageHandler } from "./MessageHandler";
|
||||
import { sendMessage } from "./MessageHandler";
|
||||
import { Diagnostics, MessageTypes } from "../Contracts/ExplorerContracts";
|
||||
import { appInsights } from "../Shared/appInsights";
|
||||
import { SeverityLevel } from "@microsoft/applicationinsights-web";
|
||||
@ -33,7 +33,7 @@ export function logError(message: string | Error, area: string, code?: number):
|
||||
}
|
||||
|
||||
function _logEntry(entry: Diagnostics.LogEntry): void {
|
||||
MessageHandler.sendMessage({
|
||||
sendMessage({
|
||||
type: MessageTypes.LogInfo,
|
||||
data: JSON.stringify(entry)
|
||||
});
|
||||
|
@ -1,65 +1,29 @@
|
||||
import Q from "q";
|
||||
import { CachedDataPromise, MessageHandler } from "./MessageHandler";
|
||||
import * as MessageHandler from "./MessageHandler";
|
||||
import { MessageTypes } from "../Contracts/ExplorerContracts";
|
||||
|
||||
class MockMessageHandler extends MessageHandler {
|
||||
public static addToMap(key: string, value: CachedDataPromise<any>): void {
|
||||
MessageHandler.RequestMap[key] = value;
|
||||
}
|
||||
|
||||
public static mapContainsKey(key: string): boolean {
|
||||
return MessageHandler.RequestMap[key] != null;
|
||||
}
|
||||
|
||||
public static clearAllEntries(): void {
|
||||
MessageHandler.RequestMap = {};
|
||||
}
|
||||
|
||||
public static runGarbageCollector(): void {
|
||||
MessageHandler.runGarbageCollector();
|
||||
}
|
||||
}
|
||||
|
||||
describe("Message Handler", () => {
|
||||
beforeEach(() => {
|
||||
MockMessageHandler.clearAllEntries();
|
||||
});
|
||||
|
||||
xit("should send cached data message", (done: any) => {
|
||||
const testValidationCallback = (e: MessageEvent) => {
|
||||
expect(e.data.data).toEqual(
|
||||
jasmine.objectContaining({ type: MessageTypes.AllDatabases, params: ["some param"] })
|
||||
);
|
||||
e.currentTarget.removeEventListener(e.type, testValidationCallback);
|
||||
done();
|
||||
};
|
||||
window.parent.addEventListener("message", testValidationCallback);
|
||||
MockMessageHandler.sendCachedDataMessage(MessageTypes.AllDatabases, ["some param"]);
|
||||
});
|
||||
|
||||
it("should handle cached message", () => {
|
||||
let mockPromise: CachedDataPromise<any> = {
|
||||
it("should handle cached message", async () => {
|
||||
let mockPromise = {
|
||||
id: "123",
|
||||
startTime: new Date(),
|
||||
deferred: Q.defer<any>()
|
||||
};
|
||||
let mockMessage = { message: { id: "123", data: "{}" } };
|
||||
|
||||
MockMessageHandler.addToMap(mockPromise.id, mockPromise);
|
||||
MockMessageHandler.handleCachedDataMessage(mockMessage);
|
||||
MessageHandler.RequestMap[mockPromise.id] = mockPromise;
|
||||
MessageHandler.handleCachedDataMessage(mockMessage);
|
||||
expect(mockPromise.deferred.promise.isFulfilled()).toBe(true);
|
||||
});
|
||||
|
||||
it("should delete fulfilled promises on running the garbage collector", () => {
|
||||
let mockPromise: CachedDataPromise<any> = {
|
||||
it("should delete fulfilled promises on running the garbage collector", async () => {
|
||||
let message = {
|
||||
id: "123",
|
||||
startTime: new Date(),
|
||||
deferred: Q.defer<any>()
|
||||
};
|
||||
|
||||
MockMessageHandler.addToMap(mockPromise.id, mockPromise);
|
||||
mockPromise.deferred.reject("some error");
|
||||
MockMessageHandler.runGarbageCollector();
|
||||
expect(MockMessageHandler.mapContainsKey(mockPromise.id)).toBe(false);
|
||||
MessageHandler.handleCachedDataMessage(message);
|
||||
MessageHandler.runGarbageCollector();
|
||||
expect(MessageHandler.RequestMap["123"]).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
@ -9,36 +9,24 @@ export interface CachedDataPromise<T> {
|
||||
id: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* For some reason, typescript emits a Map() in the compiled js output(despite the target being set to ES5) forcing us to define our own polyfill,
|
||||
* so we define our own custom implementation of the ES6 Map to work around it.
|
||||
*/
|
||||
type Map = { [key: string]: CachedDataPromise<any> };
|
||||
export const RequestMap: Record<string, CachedDataPromise<any>> = {};
|
||||
|
||||
export class MessageHandler {
|
||||
protected static RequestMap: Map = {};
|
||||
|
||||
public static handleCachedDataMessage(message: any): void {
|
||||
export function handleCachedDataMessage(message: any): void {
|
||||
const messageContent = message && message.message;
|
||||
if (
|
||||
message == null ||
|
||||
messageContent == null ||
|
||||
messageContent.id == null ||
|
||||
!MessageHandler.RequestMap[messageContent.id]
|
||||
) {
|
||||
if (message == null || messageContent == null || messageContent.id == null || !RequestMap[messageContent.id]) {
|
||||
return;
|
||||
}
|
||||
|
||||
const cachedDataPromise = MessageHandler.RequestMap[messageContent.id];
|
||||
const cachedDataPromise = RequestMap[messageContent.id];
|
||||
if (messageContent.error != null) {
|
||||
cachedDataPromise.deferred.reject(messageContent.error);
|
||||
} else {
|
||||
cachedDataPromise.deferred.resolve(JSON.parse(messageContent.data));
|
||||
}
|
||||
MessageHandler.runGarbageCollector();
|
||||
runGarbageCollector();
|
||||
}
|
||||
|
||||
public static sendCachedDataMessage<TResponseDataModel>(
|
||||
export function sendCachedDataMessage<TResponseDataModel>(
|
||||
messageType: MessageTypes,
|
||||
params: Object[],
|
||||
timeoutInMs?: number
|
||||
@ -48,8 +36,8 @@ export class MessageHandler {
|
||||
startTime: new Date(),
|
||||
id: _.uniqueId()
|
||||
};
|
||||
MessageHandler.RequestMap[cachedDataPromise.id] = cachedDataPromise;
|
||||
MessageHandler.sendMessage({ type: messageType, params: params, id: cachedDataPromise.id });
|
||||
RequestMap[cachedDataPromise.id] = cachedDataPromise;
|
||||
sendMessage({ type: messageType, params: params, id: cachedDataPromise.id });
|
||||
|
||||
//TODO: Use telemetry to measure optimal time to resolve/reject promises
|
||||
return cachedDataPromise.deferred.promise.timeout(
|
||||
@ -58,8 +46,8 @@ export class MessageHandler {
|
||||
);
|
||||
}
|
||||
|
||||
public static sendMessage(data: any): void {
|
||||
if (MessageHandler.canSendMessage()) {
|
||||
export function sendMessage(data: any): void {
|
||||
if (canSendMessage()) {
|
||||
window.parent.postMessage(
|
||||
{
|
||||
signature: "pcIframe",
|
||||
@ -70,16 +58,16 @@ export class MessageHandler {
|
||||
}
|
||||
}
|
||||
|
||||
public static canSendMessage(): boolean {
|
||||
export function canSendMessage(): boolean {
|
||||
return window.parent !== window;
|
||||
}
|
||||
|
||||
protected static runGarbageCollector() {
|
||||
Object.keys(MessageHandler.RequestMap).forEach((key: string) => {
|
||||
const promise: Q.Promise<any> = MessageHandler.RequestMap[key].deferred.promise;
|
||||
// TODO: This is exported just for testing. It should not be.
|
||||
export function runGarbageCollector() {
|
||||
Object.keys(RequestMap).forEach((key: string) => {
|
||||
const promise: Q.Promise<any> = RequestMap[key].deferred.promise;
|
||||
if (promise.isFulfilled() || promise.isRejected()) {
|
||||
delete MessageHandler.RequestMap[key];
|
||||
delete RequestMap[key];
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ import { config } from "../Config";
|
||||
import { ConsoleDataType } from "../Explorer/Menus/NotificationConsole/NotificationConsoleComponent";
|
||||
import { Constants as CosmosSDKConstants } from "@azure/cosmos";
|
||||
import { CosmosClient } from "./CosmosClient";
|
||||
import { MessageHandler } from "./MessageHandler";
|
||||
import { sendMessage } from "./MessageHandler";
|
||||
import { MessageTypes } from "../Contracts/ExplorerContracts";
|
||||
import { NotificationConsoleUtils } from "../Utils/NotificationConsoleUtils";
|
||||
import { ResourceProviderClient } from "../ResourceProvider/ResourceProviderClient";
|
||||
@ -408,7 +408,7 @@ async function errorHandling(response: Response, action: string, params: unknown
|
||||
`Error ${action}: ${errorMessage}, Payload: ${JSON.stringify(params)}`
|
||||
);
|
||||
if (response.status === HttpStatusCodes.Forbidden) {
|
||||
MessageHandler.sendMessage({ type: MessageTypes.ForbiddenError, reason: errorMessage });
|
||||
sendMessage({ type: MessageTypes.ForbiddenError, reason: errorMessage });
|
||||
return;
|
||||
}
|
||||
throw new Error(errorMessage);
|
||||
|
@ -12,7 +12,7 @@ import {
|
||||
PortalTheme
|
||||
} from "./HeatmapDatatypes";
|
||||
import { isInvalidParentFrameOrigin } from "../../Utils/MessageValidation";
|
||||
import { MessageHandler } from "../../Common/MessageHandler";
|
||||
import { sendCachedDataMessage, sendMessage } from "../../Common/MessageHandler";
|
||||
import { MessageTypes } from "../../Contracts/ExplorerContracts";
|
||||
import { StyleConstants } from "../../Common/Constants";
|
||||
import "./Heatmap.less";
|
||||
@ -209,7 +209,7 @@ export class Heatmap {
|
||||
for (let i = 0; i < this._chartData.dataPoints.length; i++) {
|
||||
output.push(this._chartData.dataPoints[i][xAxisIndex]);
|
||||
}
|
||||
MessageHandler.sendCachedDataMessage(MessageTypes.LogInfo, output);
|
||||
sendCachedDataMessage(MessageTypes.LogInfo, output);
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -266,4 +266,4 @@ export function handleMessage(event: MessageEvent) {
|
||||
}
|
||||
|
||||
window.addEventListener("message", handleMessage, false);
|
||||
MessageHandler.sendMessage("ready");
|
||||
sendMessage("ready");
|
||||
|
@ -52,7 +52,7 @@ import { isInvalidParentFrameOrigin } from "../Utils/MessageValidation";
|
||||
import { IGalleryItem } from "../Juno/JunoClient";
|
||||
import { LoadQueryPane } from "./Panes/LoadQueryPane";
|
||||
import * as Logger from "../Common/Logger";
|
||||
import { MessageHandler } from "../Common/MessageHandler";
|
||||
import { sendMessage, sendCachedDataMessage, handleCachedDataMessage } from "../Common/MessageHandler";
|
||||
import { NotebookContentItem, NotebookContentItemType } from "./Notebook/NotebookContentItem";
|
||||
import { NotebookUtil } from "./Notebook/NotebookUtil";
|
||||
import { NotebookWorkspaceManager } from "../NotebookWorkspaceManager/NotebookWorkspaceManager";
|
||||
@ -1607,7 +1607,7 @@ export default class Explorer {
|
||||
|
||||
public async getArcadiaToken(): Promise<string> {
|
||||
return new Promise<string>((resolve: (token: string) => void, reject: (error: any) => void) => {
|
||||
MessageHandler.sendCachedDataMessage<string>(MessageTypes.GetArcadiaToken, undefined /** params **/).then(
|
||||
sendCachedDataMessage<string>(MessageTypes.GetArcadiaToken, undefined /** params **/).then(
|
||||
(token: string) => {
|
||||
resolve(token);
|
||||
},
|
||||
@ -1645,11 +1645,11 @@ export default class Explorer {
|
||||
}
|
||||
|
||||
public async createWorkspace(): Promise<string> {
|
||||
return MessageHandler.sendCachedDataMessage(MessageTypes.CreateWorkspace, undefined /** params **/);
|
||||
return sendCachedDataMessage(MessageTypes.CreateWorkspace, undefined /** params **/);
|
||||
}
|
||||
|
||||
public async createSparkPool(workspaceId: string): Promise<string> {
|
||||
return MessageHandler.sendCachedDataMessage(MessageTypes.CreateSparkPool, [workspaceId]);
|
||||
return sendCachedDataMessage(MessageTypes.CreateSparkPool, [workspaceId]);
|
||||
}
|
||||
|
||||
public async initNotebooks(databaseAccount: DataModels.DatabaseAccount): Promise<void> {
|
||||
@ -1845,7 +1845,7 @@ export default class Explorer {
|
||||
}
|
||||
}
|
||||
if (message.actionType === ActionContracts.ActionType.TransmitCachedData) {
|
||||
MessageHandler.handleCachedDataMessage(message);
|
||||
handleCachedDataMessage(message);
|
||||
return;
|
||||
}
|
||||
if (message.type) {
|
||||
@ -2041,7 +2041,7 @@ export default class Explorer {
|
||||
|
||||
public signInAad = () => {
|
||||
TelemetryProcessor.trace(Action.SignInAad, undefined, { area: "Explorer" });
|
||||
MessageHandler.sendMessage({
|
||||
sendMessage({
|
||||
type: MessageTypes.AadSignIn
|
||||
});
|
||||
};
|
||||
@ -2052,21 +2052,21 @@ export default class Explorer {
|
||||
};
|
||||
|
||||
public clickHostedAccountSwitch = () => {
|
||||
MessageHandler.sendMessage({
|
||||
sendMessage({
|
||||
type: MessageTypes.UpdateAccountSwitch,
|
||||
click: true
|
||||
});
|
||||
};
|
||||
|
||||
public clickHostedDirectorySwitch = () => {
|
||||
MessageHandler.sendMessage({
|
||||
sendMessage({
|
||||
type: MessageTypes.UpdateDirectoryControl,
|
||||
click: true
|
||||
});
|
||||
};
|
||||
|
||||
public refreshDatabaseAccount = () => {
|
||||
MessageHandler.sendMessage({
|
||||
sendMessage({
|
||||
type: MessageTypes.RefreshDatabaseAccount
|
||||
});
|
||||
};
|
||||
|
@ -14,7 +14,7 @@ import * as TableConstants from "./Constants";
|
||||
import * as TableEntityProcessor from "./TableEntityProcessor";
|
||||
import * as ViewModels from "../../Contracts/ViewModels";
|
||||
import { MessageTypes } from "../../Contracts/ExplorerContracts";
|
||||
import { MessageHandler } from "../../Common/MessageHandler";
|
||||
import { sendMessage } from "../../Common/MessageHandler";
|
||||
import DocumentClientUtilityBase from "../../Common/DocumentClientUtilityBase";
|
||||
import Explorer from "../Explorer";
|
||||
|
||||
@ -738,7 +738,7 @@ export class CassandraAPIDataClient extends TableDataClient {
|
||||
|
||||
private _checkForbiddenError(reason: any) {
|
||||
if (reason && reason.code === Constants.HttpStatusCodes.Forbidden) {
|
||||
MessageHandler.sendMessage({
|
||||
sendMessage({
|
||||
type: MessageTypes.ForbiddenError,
|
||||
reason: typeof reason === "string" ? "reason" : JSON.stringify(reason)
|
||||
});
|
||||
|
@ -2,7 +2,6 @@ import * as ko from "knockout";
|
||||
import * as ViewModels from "../../Contracts/ViewModels";
|
||||
import * as Constants from "../../Common/Constants";
|
||||
import DocumentsTab from "./DocumentsTab";
|
||||
import { DataAccessUtility } from "../../Platform/Portal/DataAccessUtility";
|
||||
import Explorer from "../Explorer";
|
||||
import DocumentClientUtilityBase from "../../Common/DocumentClientUtilityBase";
|
||||
|
||||
@ -15,7 +14,7 @@ describe("Documents tab", () => {
|
||||
tabKind: ViewModels.CollectionTabKind.Documents,
|
||||
title: "",
|
||||
tabPath: "",
|
||||
documentClientUtility: new DocumentClientUtilityBase(new DataAccessUtility()),
|
||||
documentClientUtility: new DocumentClientUtilityBase(),
|
||||
selfLink: "",
|
||||
hashLocation: "",
|
||||
isActive: ko.observable<boolean>(false),
|
||||
@ -98,7 +97,7 @@ describe("Documents tab", () => {
|
||||
tabKind: ViewModels.CollectionTabKind.Documents,
|
||||
title: "",
|
||||
tabPath: "",
|
||||
documentClientUtility: new DocumentClientUtilityBase(new DataAccessUtility()),
|
||||
documentClientUtility: new DocumentClientUtilityBase(),
|
||||
selfLink: "",
|
||||
hashLocation: "",
|
||||
isActive: ko.observable<boolean>(false),
|
||||
@ -117,7 +116,7 @@ describe("Documents tab", () => {
|
||||
tabKind: ViewModels.CollectionTabKind.Documents,
|
||||
title: "",
|
||||
tabPath: "",
|
||||
documentClientUtility: new DocumentClientUtilityBase(new DataAccessUtility()),
|
||||
documentClientUtility: new DocumentClientUtilityBase(),
|
||||
selfLink: "",
|
||||
hashLocation: "",
|
||||
isActive: ko.observable<boolean>(false),
|
||||
@ -136,7 +135,7 @@ describe("Documents tab", () => {
|
||||
tabKind: ViewModels.CollectionTabKind.Documents,
|
||||
title: "",
|
||||
tabPath: "",
|
||||
documentClientUtility: new DocumentClientUtilityBase(new DataAccessUtility()),
|
||||
documentClientUtility: new DocumentClientUtilityBase(),
|
||||
selfLink: "",
|
||||
hashLocation: "",
|
||||
isActive: ko.observable<boolean>(false),
|
||||
@ -155,7 +154,7 @@ describe("Documents tab", () => {
|
||||
tabKind: ViewModels.CollectionTabKind.Documents,
|
||||
title: "",
|
||||
tabPath: "",
|
||||
documentClientUtility: new DocumentClientUtilityBase(new DataAccessUtility()),
|
||||
documentClientUtility: new DocumentClientUtilityBase(),
|
||||
selfLink: "",
|
||||
hashLocation: "",
|
||||
isActive: ko.observable<boolean>(false),
|
||||
@ -174,7 +173,7 @@ describe("Documents tab", () => {
|
||||
tabKind: ViewModels.CollectionTabKind.Documents,
|
||||
title: "",
|
||||
tabPath: "",
|
||||
documentClientUtility: new DocumentClientUtilityBase(new DataAccessUtility()),
|
||||
documentClientUtility: new DocumentClientUtilityBase(),
|
||||
selfLink: "",
|
||||
hashLocation: "",
|
||||
isActive: ko.observable<boolean>(false),
|
||||
|
@ -7,7 +7,6 @@ import Database from "../Tree/Database";
|
||||
import DocumentClientUtilityBase from "../../Common/DocumentClientUtilityBase";
|
||||
import Explorer from "../Explorer";
|
||||
import SettingsTab from "../Tabs/SettingsTab";
|
||||
import { DataAccessUtility } from "../../Platform/Portal/DataAccessUtility";
|
||||
|
||||
describe("Settings tab", () => {
|
||||
const baseCollection: DataModels.Collection = {
|
||||
@ -189,7 +188,7 @@ describe("Settings tab", () => {
|
||||
tabKind: ViewModels.CollectionTabKind.Settings,
|
||||
title: "Scale & Settings",
|
||||
tabPath: "",
|
||||
documentClientUtility: new DocumentClientUtilityBase(new DataAccessUtility()),
|
||||
documentClientUtility: new DocumentClientUtilityBase(),
|
||||
|
||||
selfLink: "",
|
||||
hashLocation: "",
|
||||
@ -213,7 +212,7 @@ describe("Settings tab", () => {
|
||||
tabKind: ViewModels.CollectionTabKind.Settings,
|
||||
title: "Scale & Settings",
|
||||
tabPath: "",
|
||||
documentClientUtility: new DocumentClientUtilityBase(new DataAccessUtility()),
|
||||
documentClientUtility: new DocumentClientUtilityBase(),
|
||||
|
||||
selfLink: "",
|
||||
hashLocation: "",
|
||||
@ -232,7 +231,7 @@ describe("Settings tab", () => {
|
||||
tabKind: ViewModels.CollectionTabKind.Settings,
|
||||
title: "Scale & Settings",
|
||||
tabPath: "",
|
||||
documentClientUtility: new DocumentClientUtilityBase(new DataAccessUtility()),
|
||||
documentClientUtility: new DocumentClientUtilityBase(),
|
||||
|
||||
selfLink: "",
|
||||
hashLocation: "",
|
||||
@ -271,7 +270,7 @@ describe("Settings tab", () => {
|
||||
tabKind: ViewModels.CollectionTabKind.Settings,
|
||||
title: "Scale & Settings",
|
||||
tabPath: "",
|
||||
documentClientUtility: new DocumentClientUtilityBase(new DataAccessUtility()),
|
||||
documentClientUtility: new DocumentClientUtilityBase(),
|
||||
|
||||
selfLink: "",
|
||||
hashLocation: "",
|
||||
@ -288,7 +287,7 @@ describe("Settings tab", () => {
|
||||
tabKind: ViewModels.CollectionTabKind.Settings,
|
||||
title: "Scale & Settings",
|
||||
tabPath: "",
|
||||
documentClientUtility: new DocumentClientUtilityBase(new DataAccessUtility()),
|
||||
documentClientUtility: new DocumentClientUtilityBase(),
|
||||
|
||||
selfLink: "",
|
||||
hashLocation: "",
|
||||
@ -314,7 +313,7 @@ describe("Settings tab", () => {
|
||||
tabKind: ViewModels.CollectionTabKind.Settings,
|
||||
title: "Scale & Settings",
|
||||
tabPath: "",
|
||||
documentClientUtility: new DocumentClientUtilityBase(new DataAccessUtility()),
|
||||
documentClientUtility: new DocumentClientUtilityBase(),
|
||||
|
||||
selfLink: "",
|
||||
hashLocation: "",
|
||||
@ -395,7 +394,7 @@ describe("Settings tab", () => {
|
||||
tabKind: ViewModels.CollectionTabKind.Settings,
|
||||
title: "Scale & Settings",
|
||||
tabPath: "",
|
||||
documentClientUtility: new DocumentClientUtilityBase(new DataAccessUtility()),
|
||||
documentClientUtility: new DocumentClientUtilityBase(),
|
||||
|
||||
selfLink: "",
|
||||
hashLocation: "",
|
||||
@ -541,7 +540,7 @@ describe("Settings tab", () => {
|
||||
tabKind: ViewModels.CollectionTabKind.Settings,
|
||||
title: "Scale & Settings",
|
||||
tabPath: "",
|
||||
documentClientUtility: new DocumentClientUtilityBase(new DataAccessUtility()),
|
||||
documentClientUtility: new DocumentClientUtilityBase(),
|
||||
|
||||
selfLink: "",
|
||||
hashLocation: "",
|
||||
|
@ -1,6 +1,5 @@
|
||||
import * as ko from "knockout";
|
||||
import * as ViewModels from "../../Contracts/ViewModels";
|
||||
import { DataAccessUtility } from "../../Platform/Portal/DataAccessUtility";
|
||||
import { TabsManager } from "./TabsManager";
|
||||
import DocumentClientUtilityBase from "../../Common/DocumentClientUtilityBase";
|
||||
import DocumentsTab from "./DocumentsTab";
|
||||
@ -64,7 +63,7 @@ describe("Tabs manager tests", () => {
|
||||
collection,
|
||||
title: "",
|
||||
tabPath: "",
|
||||
documentClientUtility: new DocumentClientUtilityBase(new DataAccessUtility()),
|
||||
documentClientUtility: new DocumentClientUtilityBase(),
|
||||
selfLink: "",
|
||||
hashLocation: "",
|
||||
isActive: ko.observable<boolean>(false),
|
||||
|
@ -1,12 +0,0 @@
|
||||
import Q from "q";
|
||||
import { DataAccessUtilityBase } from "../../Common/DataAccessUtilityBase";
|
||||
|
||||
export class DataAccessUtility extends DataAccessUtilityBase {
|
||||
public refreshCachedOffers(): Q.Promise<void> {
|
||||
return Q();
|
||||
}
|
||||
|
||||
public refreshCachedResources(options: any): Q.Promise<void> {
|
||||
return Q();
|
||||
}
|
||||
}
|
@ -4,12 +4,11 @@ import Explorer from "../../Explorer/Explorer";
|
||||
|
||||
import { NotificationsClient } from "./NotificationsClient";
|
||||
import DocumentClientUtilityBase from "../../Common/DocumentClientUtilityBase";
|
||||
import { DataAccessUtility } from "./DataAccessUtility";
|
||||
|
||||
export default class EmulatorExplorerFactory {
|
||||
public static createExplorer(): Explorer {
|
||||
DocumentClientUtilityBase;
|
||||
const documentClientUtility: DocumentClientUtilityBase = new DocumentClientUtilityBase(new DataAccessUtility());
|
||||
const documentClientUtility: DocumentClientUtilityBase = new DocumentClientUtilityBase();
|
||||
|
||||
const explorer: Explorer = new Explorer({
|
||||
documentClientUtility: documentClientUtility,
|
||||
|
@ -1,12 +0,0 @@
|
||||
import Q from "q";
|
||||
import { DataAccessUtilityBase } from "../../Common/DataAccessUtilityBase";
|
||||
|
||||
export class DataAccessUtility extends DataAccessUtilityBase {
|
||||
public refreshCachedOffers(): Q.Promise<void> {
|
||||
return Q();
|
||||
}
|
||||
|
||||
public refreshCachedResources(): Q.Promise<void> {
|
||||
return Q();
|
||||
}
|
||||
}
|
@ -1,12 +1,10 @@
|
||||
import * as ViewModels from "../../Contracts/ViewModels";
|
||||
import Explorer from "../../Explorer/Explorer";
|
||||
import { NotificationsClient } from "./NotificationsClient";
|
||||
import DocumentClientUtilityBase from "../../Common/DocumentClientUtilityBase";
|
||||
import { DataAccessUtility } from "./DataAccessUtility";
|
||||
|
||||
export default class HostedExplorerFactory {
|
||||
public createExplorer(): Explorer {
|
||||
var documentClientUtility = new DocumentClientUtilityBase(new DataAccessUtility());
|
||||
var documentClientUtility = new DocumentClientUtilityBase();
|
||||
|
||||
const explorer = new Explorer({
|
||||
documentClientUtility: documentClientUtility,
|
||||
@ -19,7 +17,7 @@ export default class HostedExplorerFactory {
|
||||
|
||||
public static reInitializeDocumentClientUtilityForExplorer(explorer: Explorer): void {
|
||||
if (!!explorer) {
|
||||
const documentClientUtility = new DocumentClientUtilityBase(new DataAccessUtility());
|
||||
const documentClientUtility = new DocumentClientUtilityBase();
|
||||
explorer.rebindDocumentClientUtility(documentClientUtility);
|
||||
explorer.notificationConsoleData([]);
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ import { CosmosClient } from "../../Common/CosmosClient";
|
||||
import { DataExplorerInputsFrame } from "../../Contracts/ViewModels";
|
||||
import { DefaultExperienceUtility } from "../../Shared/DefaultExperienceUtility";
|
||||
import { HostedUtils } from "./HostedUtils";
|
||||
import { MessageHandler } from "../../Common/MessageHandler";
|
||||
import { sendMessage } from "../../Common/MessageHandler";
|
||||
import { MessageTypes } from "../../Contracts/ExplorerContracts";
|
||||
import { SessionStorageUtility, StorageKey } from "../../Shared/StorageUtility";
|
||||
import { SubscriptionUtilMappings } from "../../Shared/Constants";
|
||||
@ -77,7 +77,7 @@ export default class Main {
|
||||
|
||||
const explorer: Explorer = this._instantiateExplorer();
|
||||
if (authType === AuthType.EncryptedToken) {
|
||||
MessageHandler.sendMessage({
|
||||
sendMessage({
|
||||
type: MessageTypes.UpdateAccountSwitch,
|
||||
props: {
|
||||
authType: AuthType.EncryptedToken,
|
||||
@ -102,7 +102,7 @@ export default class Main {
|
||||
}
|
||||
);
|
||||
} else if (authType === AuthType.AAD) {
|
||||
MessageHandler.sendMessage({
|
||||
sendMessage({
|
||||
type: MessageTypes.GetAccessAadRequest
|
||||
});
|
||||
if (this._getAadAccessDeferred != null) {
|
||||
@ -287,7 +287,7 @@ export default class Main {
|
||||
const apiExperience: string = DefaultExperienceUtility.getDefaultExperienceFromApiKind(
|
||||
Main._accessInputMetadata.apiKind
|
||||
);
|
||||
MessageHandler.sendMessage({
|
||||
sendMessage({
|
||||
type: MessageTypes.UpdateAccountSwitch,
|
||||
props: {
|
||||
authType: AuthType.EncryptedToken,
|
||||
@ -385,7 +385,7 @@ export default class Main {
|
||||
window.addEventListener(
|
||||
"click",
|
||||
() => {
|
||||
MessageHandler.sendMessage({
|
||||
sendMessage({
|
||||
type: MessageTypes.ExplorerClickEvent
|
||||
});
|
||||
},
|
||||
@ -514,7 +514,7 @@ export default class Main {
|
||||
) {
|
||||
Main._initDataExplorerFrameInputs(explorer, masterKey, account, authorizationToken);
|
||||
explorer.isAccountReady.valueHasMutated();
|
||||
MessageHandler.sendMessage("ready");
|
||||
sendMessage("ready");
|
||||
}
|
||||
|
||||
private static _shouldProcessMessage(event: MessageEvent): boolean {
|
||||
|
@ -1,96 +0,0 @@
|
||||
import "jquery";
|
||||
import * as _ from "underscore";
|
||||
import Q from "q";
|
||||
|
||||
import { getAuthorizationHeader } from "../../Utils/AuthorizationUtils";
|
||||
import * as DataModels from "../../Contracts/DataModels";
|
||||
import * as ViewModels from "../../Contracts/ViewModels";
|
||||
import * as Constants from "../../Common/Constants";
|
||||
import { DataAccessUtilityBase } from "../../Common/DataAccessUtilityBase";
|
||||
import { MessageHandler } from "../../Common/MessageHandler";
|
||||
import { MessageTypes } from "../../Contracts/ExplorerContracts";
|
||||
|
||||
export class DataAccessUtility extends DataAccessUtilityBase {
|
||||
public readDatabases(options: any): Q.Promise<DataModels.Database[]> {
|
||||
return MessageHandler.sendCachedDataMessage<DataModels.Database[]>(MessageTypes.AllDatabases, [
|
||||
(<any>window).dataExplorer.databaseAccount().id,
|
||||
Constants.ClientDefaults.portalCacheTimeoutMs
|
||||
]).catch(error => {
|
||||
return super.readDatabases(options);
|
||||
});
|
||||
}
|
||||
|
||||
// public readCollections(database: ViewModels.Database, options: any): Q.Promise<DataModels.Collection[]> {
|
||||
// return MessageHandler.sendCachedDataMessage<DataModels.Collection[]>(MessageTypes.CollectionsForDatabase, [
|
||||
// (<any>window).dataExplorer.databaseAccount().id,
|
||||
// database.id()
|
||||
// ]);
|
||||
// }
|
||||
|
||||
public readOffers(options: any): Q.Promise<DataModels.Offer[]> {
|
||||
return MessageHandler.sendCachedDataMessage<DataModels.Offer[]>(MessageTypes.AllOffers, [
|
||||
(<any>window).dataExplorer.databaseAccount().id,
|
||||
Constants.ClientDefaults.portalCacheTimeoutMs
|
||||
]).catch(error => {
|
||||
return super.readOffers(options);
|
||||
});
|
||||
}
|
||||
|
||||
public readOffer(requestedResource: DataModels.Offer, options: any): Q.Promise<DataModels.OfferWithHeaders> {
|
||||
const deferred: Q.Deferred<DataModels.OfferWithHeaders> = Q.defer<DataModels.OfferWithHeaders>();
|
||||
super.readOffer(requestedResource, options).then(
|
||||
(offer: DataModels.OfferWithHeaders) => deferred.resolve(offer),
|
||||
(reason: any) => {
|
||||
const isThrottled: boolean =
|
||||
!!reason &&
|
||||
!!reason.error &&
|
||||
!!reason.error.code &&
|
||||
reason.error.code == Constants.HttpStatusCodes.TooManyRequests;
|
||||
if (isThrottled && MessageHandler.canSendMessage()) {
|
||||
MessageHandler.sendCachedDataMessage<DataModels.OfferWithHeaders>(MessageTypes.SingleOffer, [
|
||||
(<any>window).dataExplorer.databaseAccount().id,
|
||||
requestedResource._self,
|
||||
requestedResource.offerVersion
|
||||
]).then(
|
||||
(offer: DataModels.OfferWithHeaders) => deferred.resolve(offer),
|
||||
(reason: any) => deferred.reject(reason)
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
deferred.reject(reason);
|
||||
}
|
||||
);
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
public updateOfferThroughputBeyondLimit(
|
||||
updateThroughputRequestPayload: DataModels.UpdateOfferThroughputRequest,
|
||||
options: any
|
||||
): Q.Promise<void> {
|
||||
const deferred: Q.Deferred<void> = Q.defer<void>();
|
||||
const explorer = window.dataExplorer;
|
||||
const url: string = `${explorer.extensionEndpoint()}/api/offerthroughputrequest/updatebeyondspecifiedlimit`;
|
||||
const authorizationHeader: ViewModels.AuthorizationTokenHeaderMetadata = getAuthorizationHeader();
|
||||
const requestOptions: any = _.extend({}, options, {});
|
||||
requestOptions[authorizationHeader.header] = authorizationHeader.token;
|
||||
const requestSettings: JQueryAjaxSettings<any> = {
|
||||
type: "POST",
|
||||
contentType: "application/json",
|
||||
headers: requestOptions,
|
||||
data: JSON.stringify(updateThroughputRequestPayload)
|
||||
};
|
||||
|
||||
$.ajax(url, requestSettings).then(
|
||||
(data: any, textStatus: string, xhr: JQueryXHR<any>) => {
|
||||
deferred.resolve();
|
||||
},
|
||||
(xhr: JQueryXHR<any>, textStatus: string, error: any) => {
|
||||
deferred.reject(xhr.responseText);
|
||||
}
|
||||
);
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
}
|
@ -1,13 +1,11 @@
|
||||
import * as ViewModels from "../../Contracts/ViewModels";
|
||||
import Explorer from "../../Explorer/Explorer";
|
||||
|
||||
import { NotificationsClient } from "./NotificationsClient";
|
||||
import DocumentClientUtilityBase from "../../Common/DocumentClientUtilityBase";
|
||||
import { DataAccessUtility } from "./DataAccessUtility";
|
||||
|
||||
export default class PortalExplorerFactory {
|
||||
public createExplorer(): Explorer {
|
||||
var documentClientUtility = new DocumentClientUtilityBase(new DataAccessUtility());
|
||||
var documentClientUtility = new DocumentClientUtilityBase();
|
||||
|
||||
var explorer = new Explorer({
|
||||
documentClientUtility: documentClientUtility,
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { MessageTypes } from "../Contracts/ExplorerContracts";
|
||||
import { MessageHandler } from "../Common/MessageHandler";
|
||||
import { sendMessage } from "../Common/MessageHandler";
|
||||
import { TabRouteHandler } from "./TabRouteHandler";
|
||||
|
||||
export class RouteHandler {
|
||||
@ -27,7 +27,7 @@ export class RouteHandler {
|
||||
}
|
||||
|
||||
public updateRouteHashLocation(hash: string): void {
|
||||
MessageHandler.sendMessage({
|
||||
sendMessage({
|
||||
type: MessageTypes.UpdateLocationHash,
|
||||
locationHash: hash
|
||||
});
|
||||
|
@ -7,7 +7,7 @@ import { AddDbUtilities } from "../Shared/AddDatabaseUtility";
|
||||
import { ConsoleDataType } from "../Explorer/Menus/NotificationConsole/NotificationConsoleComponent";
|
||||
import { CosmosClient } from "../Common/CosmosClient";
|
||||
import { HttpStatusCodes } from "../Common/Constants";
|
||||
import { MessageHandler } from "../Common/MessageHandler";
|
||||
import { sendMessage } from "../Common/MessageHandler";
|
||||
import { MessageTypes } from "../Contracts/ExplorerContracts";
|
||||
import { NotificationConsoleUtils } from "../Utils/NotificationConsoleUtils";
|
||||
import { ResourceProviderClient } from "../ResourceProvider/ResourceProviderClient";
|
||||
@ -108,7 +108,7 @@ export class CreateSqlCollectionUtilities {
|
||||
`Error creating collection: ${JSON.stringify(response)}`
|
||||
);
|
||||
if (response.status === HttpStatusCodes.Forbidden) {
|
||||
MessageHandler.sendMessage({ type: MessageTypes.ForbiddenError });
|
||||
sendMessage({ type: MessageTypes.ForbiddenError });
|
||||
}
|
||||
throw new Error(`Error creating collection`);
|
||||
}
|
||||
@ -202,7 +202,7 @@ export class CreateCollectionUtilities {
|
||||
`Error creating graph: ${JSON.stringify(response)}`
|
||||
);
|
||||
if (response.status === HttpStatusCodes.Forbidden) {
|
||||
MessageHandler.sendMessage({ type: MessageTypes.ForbiddenError });
|
||||
sendMessage({ type: MessageTypes.ForbiddenError });
|
||||
}
|
||||
throw new Error(`Error creating graph`);
|
||||
}
|
||||
@ -248,7 +248,7 @@ export class Utilities {
|
||||
`Error creating table: ${JSON.stringify(reason)}, Payload: ${params}`
|
||||
);
|
||||
if (reason.status === HttpStatusCodes.Forbidden) {
|
||||
MessageHandler.sendMessage({ type: MessageTypes.ForbiddenError });
|
||||
sendMessage({ type: MessageTypes.ForbiddenError });
|
||||
return;
|
||||
}
|
||||
throw new Error(`Error creating table`);
|
||||
|
@ -4,7 +4,7 @@ import { config } from "../Config";
|
||||
import { ConsoleDataType } from "../Explorer/Menus/NotificationConsole/NotificationConsoleComponent";
|
||||
import { CosmosClient } from "../Common/CosmosClient";
|
||||
import { HttpStatusCodes } from "../Common/Constants";
|
||||
import { MessageHandler } from "../Common/MessageHandler";
|
||||
import { sendMessage } from "../Common/MessageHandler";
|
||||
import { MessageTypes } from "../Contracts/ExplorerContracts";
|
||||
import { NotificationConsoleUtils } from "../Utils/NotificationConsoleUtils";
|
||||
import { ResourceProviderClient } from "../ResourceProvider/ResourceProviderClient";
|
||||
@ -164,7 +164,7 @@ export class AddDbUtilities {
|
||||
`Error creating ${dbType}: ${JSON.stringify(reason)}, Payload: ${params}`
|
||||
);
|
||||
if (reason.status === HttpStatusCodes.Forbidden) {
|
||||
MessageHandler.sendMessage({ type: MessageTypes.ForbiddenError });
|
||||
sendMessage({ type: MessageTypes.ForbiddenError });
|
||||
return;
|
||||
}
|
||||
throw new Error(`Error creating ${dbType}`);
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Action, ActionModifiers } from "./TelemetryConstants";
|
||||
import { MessageHandler } from "../../Common/MessageHandler";
|
||||
import { sendMessage } from "../../Common/MessageHandler";
|
||||
import { MessageTypes } from "../../Contracts/ExplorerContracts";
|
||||
import { appInsights } from "../appInsights";
|
||||
import { config } from "../../Config";
|
||||
@ -11,7 +11,7 @@ import { config } from "../../Config";
|
||||
// TODO: Log telemetry for StorageExplorer case/other clients as well
|
||||
export default class TelemetryProcessor {
|
||||
public static trace(action: Action, actionModifier: string = ActionModifiers.Mark, data?: any): void {
|
||||
MessageHandler.sendMessage({
|
||||
sendMessage({
|
||||
type: MessageTypes.TelemetryInfo,
|
||||
data: {
|
||||
action: Action[action],
|
||||
@ -25,7 +25,7 @@ export default class TelemetryProcessor {
|
||||
|
||||
public static traceStart(action: Action, data?: any): number {
|
||||
const timestamp: number = Date.now();
|
||||
MessageHandler.sendMessage({
|
||||
sendMessage({
|
||||
type: MessageTypes.TelemetryInfo,
|
||||
data: {
|
||||
action: Action[action],
|
||||
@ -40,7 +40,7 @@ export default class TelemetryProcessor {
|
||||
}
|
||||
|
||||
public static traceSuccess(action: Action, data?: any, timestamp?: number): void {
|
||||
MessageHandler.sendMessage({
|
||||
sendMessage({
|
||||
type: MessageTypes.TelemetryInfo,
|
||||
data: {
|
||||
action: Action[action],
|
||||
@ -54,7 +54,7 @@ export default class TelemetryProcessor {
|
||||
}
|
||||
|
||||
public static traceFailure(action: Action, data?: any, timestamp?: number): void {
|
||||
MessageHandler.sendMessage({
|
||||
sendMessage({
|
||||
type: MessageTypes.TelemetryInfo,
|
||||
data: {
|
||||
action: Action[action],
|
||||
@ -68,7 +68,7 @@ export default class TelemetryProcessor {
|
||||
}
|
||||
|
||||
public static traceCancel(action: Action, data?: any, timestamp?: number): void {
|
||||
MessageHandler.sendMessage({
|
||||
sendMessage({
|
||||
type: MessageTypes.TelemetryInfo,
|
||||
data: {
|
||||
action: Action[action],
|
||||
@ -83,7 +83,7 @@ export default class TelemetryProcessor {
|
||||
|
||||
public static traceOpen(action: Action, data?: any, timestamp?: number): number {
|
||||
const validTimestamp = timestamp || Date.now();
|
||||
MessageHandler.sendMessage({
|
||||
sendMessage({
|
||||
type: MessageTypes.TelemetryInfo,
|
||||
data: {
|
||||
action: Action[action],
|
||||
@ -99,7 +99,7 @@ export default class TelemetryProcessor {
|
||||
|
||||
public static traceMark(action: Action, data?: any, timestamp?: number): number {
|
||||
const validTimestamp = timestamp || Date.now();
|
||||
MessageHandler.sendMessage({
|
||||
sendMessage({
|
||||
type: MessageTypes.TelemetryInfo,
|
||||
data: {
|
||||
action: Action[action],
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { BindingHandlersRegisterer } from "./Bindings/BindingHandlersRegisterer";
|
||||
import { MessageHandler } from "./Common/MessageHandler";
|
||||
import { sendMessage } from "./Common/MessageHandler";
|
||||
import * as ko from "knockout";
|
||||
import Explorer from "./Explorer/Explorer";
|
||||
|
||||
@ -8,7 +8,7 @@ export const applyExplorerBindings = (explorer: Explorer) => {
|
||||
ko.applyBindings(explorer);
|
||||
// This message should ideally be sent immediately after explorer has been initialized for optimal data explorer load times.
|
||||
// TODO: Send another message to describe that the bindings have been applied, and handle message transfers accordingly in the portal
|
||||
MessageHandler.sendMessage("ready");
|
||||
sendMessage("ready");
|
||||
window.dataExplorer = explorer;
|
||||
BindingHandlersRegisterer.registerBindingHandlers();
|
||||
$("#divExplorer").show();
|
||||
|
Loading…
Reference in New Issue
Block a user