Merge branch 'master' into remove-redundant-e2e-tests

This commit is contained in:
Steve Faulkner
2020-10-06 22:32:42 -05:00
committed by GitHub
21 changed files with 82 additions and 111 deletions

View File

@@ -1,5 +1,4 @@
import { AutopilotTier } from "../Contracts/DataModels"; import { AutopilotTier } from "../Contracts/DataModels";
import { configContext } from "../ConfigContext";
import { HashMap } from "./HashMap"; import { HashMap } from "./HashMap";
export class AuthorizationEndpoints { export class AuthorizationEndpoints {
@@ -13,12 +12,6 @@ export class CodeOfConductEndpoints {
public static termsOfUse: string = "https://aka.ms/ms-terms-of-use"; public static termsOfUse: string = "https://aka.ms/ms-terms-of-use";
} }
export class BackendEndpoints {
public static localhost: string = "https://localhost:12900";
public static dev: string = "https://ext.documents-dev.windows-int.net";
public static productionPortal: string = configContext.BACKEND_ENDPOINT || "https://main.documentdb.ext.azure.com";
}
export class EndpointsRegex { export class EndpointsRegex {
public static readonly cassandra = [ public static readonly cassandra = [
"AccountEndpoint=(.*).cassandra.cosmosdb.azure.com", "AccountEndpoint=(.*).cassandra.cosmosdb.azure.com",

View File

@@ -14,7 +14,9 @@ describe("tokenProvider", () => {
}; };
beforeEach(() => { beforeEach(() => {
window.dataExplorer = { extensionEndpoint: () => "https://main.documentdb.ext.azure.com" } as any; updateConfigContext({
BACKEND_ENDPOINT: "https://main.documentdb.ext.azure.com"
});
window.fetch = jest.fn().mockImplementation(() => { window.fetch = jest.fn().mockImplementation(() => {
return { return {
json: () => "{}", json: () => "{}",
@@ -58,7 +60,9 @@ describe("getTokenFromAuthService", () => {
}); });
it("builds the correct URL in production", () => { it("builds the correct URL in production", () => {
window.dataExplorer = { extensionEndpoint: () => "https://main.documentdb.ext.azure.com" } as any; updateConfigContext({
BACKEND_ENDPOINT: "https://main.documentdb.ext.azure.com"
});
getTokenFromAuthService("GET", "dbs", "foo"); getTokenFromAuthService("GET", "dbs", "foo");
expect(window.fetch).toHaveBeenCalledWith( expect(window.fetch).toHaveBeenCalledWith(
"https://main.documentdb.ext.azure.com/api/guest/runtimeproxy/authorizationTokens", "https://main.documentdb.ext.azure.com/api/guest/runtimeproxy/authorizationTokens",

View File

@@ -52,7 +52,7 @@ export const endpoint = () => {
export async function getTokenFromAuthService(verb: string, resourceType: string, resourceId?: string): Promise<any> { export async function getTokenFromAuthService(verb: string, resourceType: string, resourceId?: string): Promise<any> {
try { try {
const host = configContext.BACKEND_ENDPOINT || _global.dataExplorer.extensionEndpoint(); const host = configContext.BACKEND_ENDPOINT;
const response = await _global.fetch(host + "/api/guest/runtimeproxy/authorizationTokens", { const response = await _global.fetch(host + "/api/guest/runtimeproxy/authorizationTokens", {
method: "POST", method: "POST",
headers: { headers: {
@@ -85,8 +85,7 @@ export function client(): Cosmos.CosmosClient {
userAgentSuffix: "Azure Portal" userAgentSuffix: "Azure Portal"
}; };
// In development we proxy requests to the backend via webpack. This is removed in production bundles. if (configContext.PROXY_PATH !== undefined) {
if (process.env.NODE_ENV === "development") {
(options as any).plugins = [{ on: "request", plugin: requestPlugin }]; (options as any).plugins = [{ on: "request", plugin: requestPlugin }];
} }
return new Cosmos.CosmosClient(options); return new Cosmos.CosmosClient(options);

View File

@@ -63,10 +63,9 @@ describe("MongoProxyClient", () => {
updateUserContext({ updateUserContext({
databaseAccount databaseAccount
}); });
window.dataExplorer = { updateConfigContext({
extensionEndpoint: () => "https://main.documentdb.ext.azure.com", BACKEND_ENDPOINT: "https://main.documentdb.ext.azure.com"
serverId: () => "" });
} as any;
window.fetch = jest.fn().mockImplementation(fetchMock); window.fetch = jest.fn().mockImplementation(fetchMock);
}); });
afterEach(() => { afterEach(() => {
@@ -96,10 +95,9 @@ describe("MongoProxyClient", () => {
updateUserContext({ updateUserContext({
databaseAccount databaseAccount
}); });
window.dataExplorer = { updateConfigContext({
extensionEndpoint: () => "https://main.documentdb.ext.azure.com", BACKEND_ENDPOINT: "https://main.documentdb.ext.azure.com"
serverId: () => "" });
} as any;
window.fetch = jest.fn().mockImplementation(fetchMock); window.fetch = jest.fn().mockImplementation(fetchMock);
}); });
afterEach(() => { afterEach(() => {
@@ -129,10 +127,9 @@ describe("MongoProxyClient", () => {
updateUserContext({ updateUserContext({
databaseAccount databaseAccount
}); });
window.dataExplorer = { updateConfigContext({
extensionEndpoint: () => "https://main.documentdb.ext.azure.com", BACKEND_ENDPOINT: "https://main.documentdb.ext.azure.com"
serverId: () => "" });
} as any;
window.fetch = jest.fn().mockImplementation(fetchMock); window.fetch = jest.fn().mockImplementation(fetchMock);
}); });
afterEach(() => { afterEach(() => {
@@ -162,10 +159,9 @@ describe("MongoProxyClient", () => {
updateUserContext({ updateUserContext({
databaseAccount databaseAccount
}); });
window.dataExplorer = { updateConfigContext({
extensionEndpoint: () => "https://main.documentdb.ext.azure.com", BACKEND_ENDPOINT: "https://main.documentdb.ext.azure.com"
serverId: () => "" });
} as any;
window.fetch = jest.fn().mockImplementation(fetchMock); window.fetch = jest.fn().mockImplementation(fetchMock);
}); });
afterEach(() => { afterEach(() => {
@@ -195,10 +191,9 @@ describe("MongoProxyClient", () => {
updateUserContext({ updateUserContext({
databaseAccount databaseAccount
}); });
window.dataExplorer = { updateConfigContext({
extensionEndpoint: () => "https://main.documentdb.ext.azure.com", BACKEND_ENDPOINT: "https://main.documentdb.ext.azure.com"
serverId: () => "" });
} as any;
window.fetch = jest.fn().mockImplementation(fetchMock); window.fetch = jest.fn().mockImplementation(fetchMock);
}); });
afterEach(() => { afterEach(() => {
@@ -229,10 +224,9 @@ describe("MongoProxyClient", () => {
updateUserContext({ updateUserContext({
databaseAccount databaseAccount
}); });
window.dataExplorer = { updateConfigContext({
extensionEndpoint: () => "https://main.documentdb.ext.azure.com", BACKEND_ENDPOINT: "https://main.documentdb.ext.azure.com"
serverId: () => "" });
} as any;
}); });
it("returns a production endpoint", () => { it("returns a production endpoint", () => {

View File

@@ -327,8 +327,7 @@ export function createMongoCollectionWithProxy(
} }
export function getEndpoint(): string { export function getEndpoint(): string {
const extensionEndpoint = window.dataExplorer.extensionEndpoint(); let url = (configContext.MONGO_BACKEND_ENDPOINT || configContext.BACKEND_ENDPOINT) + "/api/mongo/explorer";
let url = (configContext.MONGO_BACKEND_ENDPOINT || extensionEndpoint) + "/api/mongo/explorer";
if (window.authType === AuthType.EncryptedToken) { if (window.authType === AuthType.EncryptedToken) {
url = url.replace("api/mongo", "api/guest/mongo"); url = url.replace("api/mongo", "api/guest/mongo");

View File

@@ -9,8 +9,7 @@ describe("updateOfferThroughputBeyondLimit", () => {
}); });
window.dataExplorer = { window.dataExplorer = {
logConsoleData: jest.fn(), logConsoleData: jest.fn(),
deleteInProgressConsoleDataWithId: jest.fn(), deleteInProgressConsoleDataWithId: jest.fn()
extensionEndpoint: jest.fn()
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
} as any; } as any;
await updateOfferThroughputBeyondLimit({ await updateOfferThroughputBeyondLimit({

View File

@@ -28,8 +28,7 @@ export async function updateOfferThroughputBeyondLimit(request: UpdateOfferThrou
`Requesting increase in throughput to ${request.throughput} for ${resourceDescriptionInfo}` `Requesting increase in throughput to ${request.throughput} for ${resourceDescriptionInfo}`
); );
const explorer = window.dataExplorer; const url = `${configContext.BACKEND_ENDPOINT}/api/offerthroughputrequest/updatebeyondspecifiedlimit`;
const url = `${explorer.extensionEndpoint()}/api/offerthroughputrequest/updatebeyondspecifiedlimit`;
const authorizationHeader = getAuthorizationHeader(); const authorizationHeader = getAuthorizationHeader();
const response = await fetch(url, { const response = await fetch(url, {

View File

@@ -1,31 +1,25 @@
jest.mock("../../../Juno/JunoClient");
import { shallow } from "enzyme"; import { shallow } from "enzyme";
import * as sinon from "sinon";
import React from "react"; import React from "react";
import { CodeOfConductComponent, CodeOfConductComponentProps } from "./CodeOfConductComponent"; import { CodeOfConductComponent, CodeOfConductComponentProps } from "./CodeOfConductComponent";
import { IJunoResponse, JunoClient } from "../../../Juno/JunoClient"; import { JunoClient } from "../../../Juno/JunoClient";
import { HttpStatusCodes } from "../../../Common/Constants"; import { HttpStatusCodes } from "../../../Common/Constants";
describe("CodeOfConductComponent", () => { describe("CodeOfConductComponent", () => {
let sandbox: sinon.SinonSandbox;
let codeOfConductProps: CodeOfConductComponentProps; let codeOfConductProps: CodeOfConductComponentProps;
beforeEach(() => { beforeEach(() => {
sandbox = sinon.sandbox.create(); const junoClient = new JunoClient(undefined);
sandbox.stub(JunoClient.prototype, "acceptCodeOfConduct").returns({ junoClient.acceptCodeOfConduct = jest.fn().mockReturnValue({
status: HttpStatusCodes.OK, status: HttpStatusCodes.OK,
data: true data: true
} as IJunoResponse<boolean>); });
const junoClient = new JunoClient(undefined);
codeOfConductProps = { codeOfConductProps = {
junoClient: junoClient, junoClient: junoClient,
onAcceptCodeOfConduct: jest.fn() onAcceptCodeOfConduct: jest.fn()
}; };
}); });
afterEach(() => {
sandbox.restore();
});
it("renders", () => { it("renders", () => {
const wrapper = shallow(<CodeOfConductComponent {...codeOfConductProps} />); const wrapper = shallow(<CodeOfConductComponent {...codeOfConductProps} />);
expect(wrapper).toMatchSnapshot(); expect(wrapper).toMatchSnapshot();

View File

@@ -953,7 +953,6 @@ exports[`SettingsComponent renders 1`] = `
"validPartitionKeyValue": [Function], "validPartitionKeyValue": [Function],
"visible": [Function], "visible": [Function],
}, },
"extensionEndpoint": [Function],
"features": [Function], "features": [Function],
"flight": [Function], "flight": [Function],
"graphStylingPane": GraphStylingPane { "graphStylingPane": GraphStylingPane {
@@ -2268,7 +2267,6 @@ exports[`SettingsComponent renders 1`] = `
"validPartitionKeyValue": [Function], "validPartitionKeyValue": [Function],
"visible": [Function], "visible": [Function],
}, },
"extensionEndpoint": [Function],
"features": [Function], "features": [Function],
"flight": [Function], "flight": [Function],
"graphStylingPane": GraphStylingPane { "graphStylingPane": GraphStylingPane {
@@ -3596,7 +3594,6 @@ exports[`SettingsComponent renders 1`] = `
"validPartitionKeyValue": [Function], "validPartitionKeyValue": [Function],
"visible": [Function], "visible": [Function],
}, },
"extensionEndpoint": [Function],
"features": [Function], "features": [Function],
"flight": [Function], "flight": [Function],
"graphStylingPane": GraphStylingPane { "graphStylingPane": GraphStylingPane {
@@ -4911,7 +4908,6 @@ exports[`SettingsComponent renders 1`] = `
"validPartitionKeyValue": [Function], "validPartitionKeyValue": [Function],
"visible": [Function], "visible": [Function],
}, },
"extensionEndpoint": [Function],
"features": [Function], "features": [Function],
"flight": [Function], "flight": [Function],
"graphStylingPane": GraphStylingPane { "graphStylingPane": GraphStylingPane {

View File

@@ -1,12 +1,11 @@
jest.mock("../../Common/DocumentClientUtilityBase"); jest.mock("../../Common/DocumentClientUtilityBase");
jest.mock("../Graph/GraphExplorerComponent/GremlinClient");
jest.mock("../../Common/dataAccess/createCollection"); jest.mock("../../Common/dataAccess/createCollection");
import * as ko from "knockout"; import * as ko from "knockout";
import * as sinon from "sinon";
import * as ViewModels from "../../Contracts/ViewModels"; import * as ViewModels from "../../Contracts/ViewModels";
import Q from "q"; import Q from "q";
import { ContainerSampleGenerator } from "./ContainerSampleGenerator"; import { ContainerSampleGenerator } from "./ContainerSampleGenerator";
import * as DocumentClientUtility from "../../Common/DocumentClientUtilityBase"; import { createDocument } from "../../Common/DocumentClientUtilityBase";
import { GremlinClient } from "../Graph/GraphExplorerComponent/GremlinClient";
import Explorer from "../Explorer"; import Explorer from "../Explorer";
import { updateUserContext } from "../../UserContext"; import { updateUserContext } from "../../UserContext";
@@ -26,6 +25,10 @@ describe("ContainerSampleGenerator", () => {
return explorerStub; return explorerStub;
}; };
beforeEach(() => {
(createDocument as jest.Mock).mockResolvedValue(undefined);
});
it("should insert documents for sql API account", async () => { it("should insert documents for sql API account", async () => {
const sampleCollectionId = "SampleCollection"; const sampleCollectionId = "SampleCollection";
const sampleDatabaseId = "SampleDB"; const sampleDatabaseId = "SampleDB";
@@ -69,13 +72,10 @@ describe("ContainerSampleGenerator", () => {
await generator.createSampleContainerAsync(); await generator.createSampleContainerAsync();
expect(DocumentClientUtility.createDocument).toHaveBeenCalled(); expect(createDocument).toHaveBeenCalled();
}); });
it("should send gremlin queries for Graph API account", async () => { it("should send gremlin queries for Graph API account", async () => {
sinon.stub(GremlinClient.prototype, "initialize").callsFake(() => {});
const executeStub = sinon.stub(GremlinClient.prototype, "execute").returns(Q.resolve());
updateUserContext({ updateUserContext({
databaseAccount: { databaseAccount: {
id: "foo", id: "foo",
@@ -121,9 +121,6 @@ describe("ContainerSampleGenerator", () => {
generator.setData(sampleData); generator.setData(sampleData);
await generator.createSampleContainerAsync(); await generator.createSampleContainerAsync();
expect(DocumentClientUtility.createDocument).toHaveBeenCalled();
expect(executeStub.called).toBe(true);
}); });
it("should not create any sample for Mongo API account", async () => { it("should not create any sample for Mongo API account", async () => {
@@ -133,7 +130,7 @@ describe("ContainerSampleGenerator", () => {
explorerStub.defaultExperience = ko.observable<string>(experience); explorerStub.defaultExperience = ko.observable<string>(experience);
// Rejects with error that contains experience // Rejects with error that contains experience
await expect(ContainerSampleGenerator.createSampleGeneratorAsync(explorerStub)).rejects.toMatch(experience); expect(ContainerSampleGenerator.createSampleGeneratorAsync(explorerStub)).rejects.toMatch(experience);
}); });
it("should not create any sample for Table API account", async () => { it("should not create any sample for Table API account", async () => {

View File

@@ -1,7 +1,6 @@
import * as DataModels from "../../Contracts/DataModels"; import * as DataModels from "../../Contracts/DataModels";
import * as ViewModels from "../../Contracts/ViewModels"; import * as ViewModels from "../../Contracts/ViewModels";
import GraphTab from ".././Tabs/GraphTab"; import GraphTab from ".././Tabs/GraphTab";
import { ConsoleDataType } from "../Menus/NotificationConsole/NotificationConsoleComponent";
import { GremlinClient } from "../Graph/GraphExplorerComponent/GremlinClient"; import { GremlinClient } from "../Graph/GraphExplorerComponent/GremlinClient";
import * as NotificationConsoleUtils from "../../Utils/NotificationConsoleUtils"; import * as NotificationConsoleUtils from "../../Utils/NotificationConsoleUtils";
import Explorer from "../Explorer"; import Explorer from "../Explorer";
@@ -96,9 +95,9 @@ export class ContainerSampleGenerator {
.reduce((previous, current) => previous.then(current), Promise.resolve()); .reduce((previous, current) => previous.then(current), Promise.resolve());
} else { } else {
// For SQL all queries are executed at the same time // For SQL all queries are executed at the same time
this.sampleDataFile.data.forEach(doc => { this.sampleDataFile.data.map(doc => {
const subPromise = createDocument(collection, doc); const subPromise = createDocument(collection, doc);
subPromise.catch(reason => NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.Error, reason)); subPromise.catch(reason => NotificationConsoleUtils.logConsoleError(reason));
promises.push(subPromise); promises.push(subPromise);
}); });
await Promise.all(promises); await Promise.all(promises);

View File

@@ -140,7 +140,6 @@ export default class Explorer {
public canSaveQueries: ko.Computed<boolean>; public canSaveQueries: ko.Computed<boolean>;
public features: ko.Observable<any>; public features: ko.Observable<any>;
public serverId: ko.Observable<string>; public serverId: ko.Observable<string>;
public extensionEndpoint: ko.Observable<string>;
public armEndpoint: ko.Observable<string>; public armEndpoint: ko.Observable<string>;
public isTryCosmosDBSubscription: ko.Observable<boolean>; public isTryCosmosDBSubscription: ko.Observable<boolean>;
public notificationsClient: NotificationsClientBase; public notificationsClient: NotificationsClientBase;
@@ -383,7 +382,6 @@ export default class Explorer {
this.features = ko.observable(); this.features = ko.observable();
this.serverId = ko.observable<string>(); this.serverId = ko.observable<string>();
this.extensionEndpoint = ko.observable<string>(undefined);
this.armEndpoint = ko.observable<string>(undefined); this.armEndpoint = ko.observable<string>(undefined);
this.queriesClient = new QueriesClient(this); this.queriesClient = new QueriesClient(this);
this.isTryCosmosDBSubscription = ko.observable<boolean>(false); this.isTryCosmosDBSubscription = ko.observable<boolean>(false);
@@ -1912,9 +1910,8 @@ export default class Explorer {
} }
this.features(inputs.features); this.features(inputs.features);
this.serverId(inputs.serverId); this.serverId(inputs.serverId);
this.extensionEndpoint(inputs.extensionEndpoint || "");
this.armEndpoint(EnvironmentUtility.normalizeArmEndpointUri(inputs.csmEndpoint || configContext.ARM_ENDPOINT)); this.armEndpoint(EnvironmentUtility.normalizeArmEndpointUri(inputs.csmEndpoint || configContext.ARM_ENDPOINT));
this.notificationsClient.setExtensionEndpoint(this.extensionEndpoint()); this.notificationsClient.setExtensionEndpoint(configContext.BACKEND_ENDPOINT);
this.databaseAccount(databaseAccount); this.databaseAccount(databaseAccount);
this.subscriptionType(inputs.subscriptionType); this.subscriptionType(inputs.subscriptionType);
this.quotaId(inputs.quotaId); this.quotaId(inputs.quotaId);
@@ -1930,6 +1927,7 @@ export default class Explorer {
this._importExplorerConfigComplete = true; this._importExplorerConfigComplete = true;
updateConfigContext({ updateConfigContext({
BACKEND_ENDPOINT: inputs.extensionEndpoint || "",
ARM_ENDPOINT: this.armEndpoint() ARM_ENDPOINT: this.armEndpoint()
}); });
@@ -2633,7 +2631,7 @@ export default class Explorer {
const databaseAccount = this.databaseAccount(); const databaseAccount = this.databaseAccount();
const databaseAccountLocation = databaseAccount && databaseAccount.location.toLowerCase(); const databaseAccountLocation = databaseAccount && databaseAccount.location.toLowerCase();
const disallowedLocationsUri = `${this.extensionEndpoint()}/api/disallowedLocations`; const disallowedLocationsUri = `${configContext.BACKEND_ENDPOINT}/api/disallowedLocations`;
const authorizationHeader = getAuthorizationHeader(); const authorizationHeader = getAuthorizationHeader();
try { try {
const response = await fetch(disallowedLocationsUri, { const response = await fetch(disallowedLocationsUri, {
@@ -3130,8 +3128,10 @@ export default class Explorer {
} }
public async loadDatabaseOffers(): Promise<void> { public async loadDatabaseOffers(): Promise<void> {
this.databases()?.forEach(async (database: ViewModels.Database) => { await Promise.all(
await database.loadOffer(); this.databases()?.map(async (database: ViewModels.Database) => {
}); await database.loadOffer();
})
);
} }
} }

View File

@@ -32,13 +32,11 @@ export class ArraysByKeyCache<T> {
this.cache[key] = elements; this.cache[key] = elements;
if (index < 0) { if (index < 0) {
console.error("Inserting with negative index is not allowed by ArraysByCache");
return; return;
} }
// Check that previous index is populated, if not, ignore // Check that previous index is populated, if not, ignore
if (index > elements.length) { if (index > elements.length) {
console.error("Inserting non-contiguous element is not allowed by ArraysByCache");
return; return;
} }

View File

@@ -192,7 +192,6 @@ export class GremlinClient {
} }
private static reportError(msg: string): void { private static reportError(msg: string): void {
console.error(msg);
NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.Error, msg); NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.Error, msg);
Logger.logError(msg, GremlinClient.LOG_AREA); Logger.logError(msg, GremlinClient.LOG_AREA);
} }

View File

@@ -136,7 +136,6 @@ export class GremlinSimpleClient {
const data = typeof msg.data === "string" ? msg.data : new TextDecoder("utf-8").decode(msg.data); const data = typeof msg.data === "string" ? msg.data : new TextDecoder("utf-8").decode(msg.data);
return JSON.parse(data); return JSON.parse(data);
} catch (e) { } catch (e) {
console.error(e, msg);
if (this.params.failureCallback) { if (this.params.failureCallback) {
this.params.failureCallback( this.params.failureCallback(
null, null,

View File

@@ -0,0 +1,6 @@
/* eslint-disable */
export class GremlinClient {
constructor() {}
initialize() {}
execute() {}
}

View File

@@ -22,6 +22,7 @@ import {
updateDocument, updateDocument,
createDocument createDocument
} from "../../Common/DocumentClientUtilityBase"; } from "../../Common/DocumentClientUtilityBase";
import { configContext } from "../../ConfigContext";
export interface CassandraTableKeys { export interface CassandraTableKeys {
partitionKeys: CassandraTableKey[]; partitionKeys: CassandraTableKey[];
@@ -307,7 +308,7 @@ export class CassandraAPIDataClient extends TableDataClient {
authType === AuthType.EncryptedToken authType === AuthType.EncryptedToken
? Constants.CassandraBackend.guestQueryApi ? Constants.CassandraBackend.guestQueryApi
: Constants.CassandraBackend.queryApi; : Constants.CassandraBackend.queryApi;
$.ajax(`${collection.container.extensionEndpoint()}/${apiEndpoint}`, { $.ajax(`${configContext.BACKEND_ENDPOINT}/${apiEndpoint}`, {
type: "POST", type: "POST",
data: { data: {
accountName: collection && collection.container.databaseAccount && collection.container.databaseAccount().name, accountName: collection && collection.container.databaseAccount && collection.container.databaseAccount().name,
@@ -558,7 +559,7 @@ export class CassandraAPIDataClient extends TableDataClient {
authType === AuthType.EncryptedToken authType === AuthType.EncryptedToken
? Constants.CassandraBackend.guestKeysApi ? Constants.CassandraBackend.guestKeysApi
: Constants.CassandraBackend.keysApi; : Constants.CassandraBackend.keysApi;
let endpoint = `${collection.container.extensionEndpoint()}/${apiEndpoint}`; let endpoint = `${configContext.BACKEND_ENDPOINT}/${apiEndpoint}`;
const deferred = Q.defer<CassandraTableKeys>(); const deferred = Q.defer<CassandraTableKeys>();
$.ajax(endpoint, { $.ajax(endpoint, {
type: "POST", type: "POST",
@@ -613,7 +614,7 @@ export class CassandraAPIDataClient extends TableDataClient {
authType === AuthType.EncryptedToken authType === AuthType.EncryptedToken
? Constants.CassandraBackend.guestSchemaApi ? Constants.CassandraBackend.guestSchemaApi
: Constants.CassandraBackend.schemaApi; : Constants.CassandraBackend.schemaApi;
let endpoint = `${collection.container.extensionEndpoint()}/${apiEndpoint}`; let endpoint = `${configContext.BACKEND_ENDPOINT}/${apiEndpoint}`;
const deferred = Q.defer<CassandraTableKey[]>(); const deferred = Q.defer<CassandraTableKey[]>();
$.ajax(endpoint, { $.ajax(endpoint, {
type: "POST", type: "POST",
@@ -667,7 +668,7 @@ export class CassandraAPIDataClient extends TableDataClient {
authType === AuthType.EncryptedToken authType === AuthType.EncryptedToken
? Constants.CassandraBackend.guestCreateOrDeleteApi ? Constants.CassandraBackend.guestCreateOrDeleteApi
: Constants.CassandraBackend.createOrDeleteApi; : Constants.CassandraBackend.createOrDeleteApi;
$.ajax(`${explorer.extensionEndpoint()}/${apiEndpoint}`, { $.ajax(`${configContext.BACKEND_ENDPOINT}/${apiEndpoint}`, {
type: "POST", type: "POST",
data: { data: {
accountName: explorer.databaseAccount() && explorer.databaseAccount().name, accountName: explorer.databaseAccount() && explorer.databaseAccount().name,

View File

@@ -13,6 +13,7 @@ import * as NotificationConsoleUtils from "../../Utils/NotificationConsoleUtils"
import { PlatformType } from "../../PlatformType"; import { PlatformType } from "../../PlatformType";
import Explorer from "../Explorer"; import Explorer from "../Explorer";
import { userContext } from "../../UserContext"; import { userContext } from "../../UserContext";
import { configContext } from "../../ConfigContext";
export default class MongoShellTab extends TabsBase { export default class MongoShellTab extends TabsBase {
public url: ko.Computed<string>; public url: ko.Computed<string>;
@@ -30,9 +31,8 @@ export default class MongoShellTab extends TabsBase {
const accountName = account && account.name; const accountName = account && account.name;
const mongoEndpoint = account && (account.properties.mongoEndpoint || account.properties.documentEndpoint); const mongoEndpoint = account && (account.properties.mongoEndpoint || account.properties.documentEndpoint);
this._runtimeEndpoint = this._runtimeEndpoint = window.dataExplorerPlatform === PlatformType.Hosted ? configContext.BACKEND_ENDPOINT : "";
window.dataExplorerPlatform == PlatformType.Hosted ? AuthHeadersUtil.extensionEndpoint : ""; const extensionEndpoint: string = configContext.BACKEND_ENDPOINT || this._runtimeEndpoint || "";
const extensionEndpoint: string = this._container.extensionEndpoint() || this._runtimeEndpoint || "";
let baseUrl = "/content/mongoshell/dist/"; let baseUrl = "/content/mongoshell/dist/";
if (this._container.serverId() === "localhost") { if (this._container.serverId() === "localhost") {
baseUrl = "/content/mongoshell/"; baseUrl = "/content/mongoshell/";
@@ -108,7 +108,7 @@ export default class MongoShellTab extends TabsBase {
) + Constants.MongoDBAccounts.defaultPort.toString(); ) + Constants.MongoDBAccounts.defaultPort.toString();
const databaseId = this.collection.databaseId; const databaseId = this.collection.databaseId;
const collectionId = this.collection.id(); const collectionId = this.collection.id();
const apiEndpoint = this._container.extensionEndpoint(); const apiEndpoint = configContext.BACKEND_ENDPOINT;
const encryptedAuthToken: string = userContext.accessToken; const encryptedAuthToken: string = userContext.accessToken;
shellIframe.contentWindow.postMessage( shellIframe.contentWindow.postMessage(
@@ -125,7 +125,7 @@ export default class MongoShellTab extends TabsBase {
apiEndpoint: apiEndpoint apiEndpoint: apiEndpoint
} }
}, },
this._container.extensionEndpoint() configContext.BACKEND_ENDPOINT
); );
} }

View File

@@ -12,8 +12,6 @@ import { configContext } from "../../ConfigContext";
import { userContext } from "../../UserContext"; import { userContext } from "../../UserContext";
export default class AuthHeadersUtil { export default class AuthHeadersUtil {
// TODO: Figure out a way to determine the extension endpoint and serverId at runtime
public static extensionEndpoint: string = Constants.BackendEndpoints.productionPortal;
public static serverId: string = Constants.ServerIds.productionPortal; public static serverId: string = Constants.ServerIds.productionPortal;
private static readonly _firstPartyAppId: string = "203f1145-856a-4232-83d4-a43568fba23d"; private static readonly _firstPartyAppId: string = "203f1145-856a-4232-83d4-a43568fba23d";
@@ -41,7 +39,7 @@ export default class AuthHeadersUtil {
public static getAccessInputMetadata(accessInput: string): Q.Promise<DataModels.AccessInputMetadata> { public static getAccessInputMetadata(accessInput: string): Q.Promise<DataModels.AccessInputMetadata> {
const deferred: Q.Deferred<DataModels.AccessInputMetadata> = Q.defer<DataModels.AccessInputMetadata>(); const deferred: Q.Deferred<DataModels.AccessInputMetadata> = Q.defer<DataModels.AccessInputMetadata>();
const url: string = `${AuthHeadersUtil.extensionEndpoint}${Constants.ApiEndpoints.guestRuntimeProxy}/accessinputmetadata`; const url = `${configContext.BACKEND_ENDPOINT}${Constants.ApiEndpoints.guestRuntimeProxy}/accessinputmetadata`;
const authType: string = (<any>window).authType; const authType: string = (<any>window).authType;
const headers: { [headerName: string]: string } = {}; const headers: { [headerName: string]: string } = {};
@@ -86,9 +84,7 @@ export default class AuthHeadersUtil {
} }
public static generateEncryptedToken(): Q.Promise<DataModels.GenerateTokenResponse> { public static generateEncryptedToken(): Q.Promise<DataModels.GenerateTokenResponse> {
const url: string = `${ const url = configContext.BACKEND_ENDPOINT + "/api/tokens/generateToken" + AuthHeadersUtil._generateResourceUrl();
AuthHeadersUtil.extensionEndpoint
}/api/tokens/generateToken${AuthHeadersUtil._generateResourceUrl()}`;
const explorer = window.dataExplorer; const explorer = window.dataExplorer;
const headers: any = { authorization: userContext.authorizationToken }; const headers: any = { authorization: userContext.authorizationToken };
headers[Constants.HttpHeaders.getReadOnlyKey] = !explorer.hasWriteAccess(); headers[Constants.HttpHeaders.getReadOnlyKey] = !explorer.hasWriteAccess();
@@ -109,7 +105,7 @@ export default class AuthHeadersUtil {
return Q.reject("None or empty connection string specified"); return Q.reject("None or empty connection string specified");
} }
const url: string = `${AuthHeadersUtil.extensionEndpoint}/api/guest/tokens/generateToken`; const url = configContext.BACKEND_ENDPOINT + "/api/guest/tokens/generateToken";
const headers: any = {}; const headers: any = {};
headers[Constants.HttpHeaders.connectionString] = connectionString; headers[Constants.HttpHeaders.connectionString] = connectionString;

View File

@@ -24,12 +24,12 @@ import { SubscriptionUtilMappings } from "../../Shared/Constants";
import "../../Explorer/Tables/DataTable/DataTableBindingManager"; import "../../Explorer/Tables/DataTable/DataTableBindingManager";
import Explorer from "../../Explorer/Explorer"; import Explorer from "../../Explorer/Explorer";
import { updateUserContext } from "../../UserContext"; import { updateUserContext } from "../../UserContext";
import { configContext } from "../../ConfigContext";
export default class Main { export default class Main {
private static _databaseAccountId: string; private static _databaseAccountId: string;
private static _encryptedToken: string; private static _encryptedToken: string;
private static _accessInputMetadata: AccessInputMetadata; private static _accessInputMetadata: AccessInputMetadata;
private static _defaultSubscriptionType: ViewModels.SubscriptionType = ViewModels.SubscriptionType.Free;
private static _features: { [key: string]: string }; private static _features: { [key: string]: string };
// For AAD, Need to post message to hosted frame to do the auth // For AAD, Need to post message to hosted frame to do the auth
// Use local deferred variable as work around until we find better solution // Use local deferred variable as work around until we find better solution
@@ -315,7 +315,7 @@ export default class Main {
csmEndpoint: undefined, csmEndpoint: undefined,
dnsSuffix: null, dnsSuffix: null,
serverId: serverId, serverId: serverId,
extensionEndpoint: AuthHeadersUtil.extensionEndpoint, extensionEndpoint: configContext.BACKEND_ENDPOINT,
subscriptionType: CollectionCreation.DefaultSubscriptionType, subscriptionType: CollectionCreation.DefaultSubscriptionType,
quotaId: undefined, quotaId: undefined,
addCollectionDefaultFlight: explorer.flight(), addCollectionDefaultFlight: explorer.flight(),
@@ -335,7 +335,7 @@ export default class Main {
csmEndpoint: undefined, csmEndpoint: undefined,
dnsSuffix: null, dnsSuffix: null,
serverId: serverId, serverId: serverId,
extensionEndpoint: AuthHeadersUtil.extensionEndpoint, extensionEndpoint: configContext.BACKEND_ENDPOINT,
subscriptionType: CollectionCreation.DefaultSubscriptionType, subscriptionType: CollectionCreation.DefaultSubscriptionType,
quotaId: undefined, quotaId: undefined,
addCollectionDefaultFlight: explorer.flight(), addCollectionDefaultFlight: explorer.flight(),
@@ -365,7 +365,7 @@ export default class Main {
csmEndpoint: undefined, csmEndpoint: undefined,
dnsSuffix: null, dnsSuffix: null,
serverId: serverId, serverId: serverId,
extensionEndpoint: AuthHeadersUtil.extensionEndpoint, extensionEndpoint: configContext.BACKEND_ENDPOINT,
subscriptionType: CollectionCreation.DefaultSubscriptionType, subscriptionType: CollectionCreation.DefaultSubscriptionType,
quotaId: undefined, quotaId: undefined,
addCollectionDefaultFlight: explorer.flight(), addCollectionDefaultFlight: explorer.flight(),
@@ -453,11 +453,6 @@ export default class Main {
return connectionString && connectionString.includes("type=resource"); return connectionString && connectionString.includes("type=resource");
} }
private static _getSubscriptionTypeFromQuotaId(quotaId: string): ViewModels.SubscriptionType {
const subscriptionType: ViewModels.SubscriptionType = SubscriptionUtilMappings.SubscriptionTypeMap[quotaId];
return subscriptionType || Main._defaultSubscriptionType;
}
private static _renewExplorerAccessWithResourceToken = ( private static _renewExplorerAccessWithResourceToken = (
explorer: Explorer, explorer: Explorer,
connectionString: string connectionString: string

View File

@@ -7,7 +7,7 @@ import { JupyterLabAppFactory } from "./JupyterLabAppFactory";
import { Action } from "../Shared/Telemetry/TelemetryConstants"; import { Action } from "../Shared/Telemetry/TelemetryConstants";
import * as TelemetryProcessor from "../Shared/Telemetry/TelemetryProcessor"; import * as TelemetryProcessor from "../Shared/Telemetry/TelemetryProcessor";
import { updateUserContext } from "../UserContext"; import { updateUserContext } from "../UserContext";
import { TerminalQueryParams } from "../Common/Constants"; import { HttpHeaders, TerminalQueryParams } from "../Common/Constants";
const getUrlVars = (): { [key: string]: string } => { const getUrlVars = (): { [key: string]: string } => {
const vars: { [key: string]: string } = {}; const vars: { [key: string]: string } = {};
@@ -20,16 +20,20 @@ const getUrlVars = (): { [key: string]: string } => {
const createServerSettings = (urlVars: { [key: string]: string }): ServerConnection.ISettings => { const createServerSettings = (urlVars: { [key: string]: string }): ServerConnection.ISettings => {
let body: BodyInit; let body: BodyInit;
let headers: HeadersInit;
if (urlVars.hasOwnProperty(TerminalQueryParams.TerminalEndpoint)) { if (urlVars.hasOwnProperty(TerminalQueryParams.TerminalEndpoint)) {
body = JSON.stringify({ body = JSON.stringify({
endpoint: urlVars[TerminalQueryParams.TerminalEndpoint] endpoint: urlVars[TerminalQueryParams.TerminalEndpoint]
}); });
headers = {
[HttpHeaders.contentType]: "application/json"
};
} }
const server = urlVars[TerminalQueryParams.Server]; const server = urlVars[TerminalQueryParams.Server];
let options: Partial<ServerConnection.ISettings> = { let options: Partial<ServerConnection.ISettings> = {
baseUrl: server, baseUrl: server,
init: { body }, init: { body, headers },
fetch: window.parent.fetch fetch: window.parent.fetch
}; };
if (urlVars.hasOwnProperty(TerminalQueryParams.Token)) { if (urlVars.hasOwnProperty(TerminalQueryParams.Token)) {
@@ -37,7 +41,7 @@ const createServerSettings = (urlVars: { [key: string]: string }): ServerConnect
baseUrl: server, baseUrl: server,
token: urlVars[TerminalQueryParams.Token], token: urlVars[TerminalQueryParams.Token],
appendToken: true, appendToken: true,
init: { body }, init: { body, headers },
fetch: window.parent.fetch fetch: window.parent.fetch
}; };
} }