Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 56 additions & 5 deletions AISKULight/Tests/Unit/src/dynamicconfig.tests.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { AITestClass, Assert } from "@microsoft/ai-test-framework";
import { AITestClass, Assert, PollingAssert } from "@microsoft/ai-test-framework";
import { IConfig } from "@microsoft/applicationinsights-common";
import { IConfiguration, newId } from "@microsoft/applicationinsights-core-js";
import { ApplicationInsights } from "../../../src/index";
import { IConfiguration, isString, newId } from "@microsoft/applicationinsights-core-js";
import { ApplicationInsights, ISenderConfig } from "../../../src/index";
import { createAsyncResolvedPromise } from "@nevware21/ts-async";

export class ApplicationInsightsDynamicConfigTests extends AITestClass {
private static readonly _instrumentationKey = "b7170927-2d1c-44f1-acec-59f4e1751c11";
Expand All @@ -10,6 +11,7 @@ export class ApplicationInsightsDynamicConfigTests extends AITestClass {
private _sessionPrefix: string = newId();
private _config: IConfiguration & IConfig;
static registerTests: any;
private _ctx: any;

constructor(testName?: string) {
super(testName || "AISKU Dynamic Config");
Expand All @@ -27,6 +29,7 @@ export class ApplicationInsightsDynamicConfigTests extends AITestClass {
this._config = this._getTestConfig(this._sessionPrefix);

this._ai = new ApplicationInsights(this._config);
this._ctx = {};
} catch (e) {
console.error("Failed to initialize", e);
}
Expand All @@ -37,6 +40,7 @@ export class ApplicationInsightsDynamicConfigTests extends AITestClass {
// force unload
this._ai.unload(false);
}
this._ctx = null;

console.log("* testCleanup(" + (AITestClass.currentTestInfo ? AITestClass.currentTestInfo.name : "<null>") + ")");
}
Expand Down Expand Up @@ -72,20 +76,67 @@ export class ApplicationInsightsDynamicConfigTests extends AITestClass {
Assert.equal(expectedLoggingLevel, details.cfg.diagnosticLogInterval, "Expect the diagnosticLogInterval to be set");
});

Assert.equal(1, onChangeCalled, "OnCfgChange was not called");
Assert.equal(1, onChangeCalled, "OnCfgChange was called once");

expectedIkey = "newIkey";
expectedConnectionString = `InstrumentationKey=${expectedIkey}`;
config.connectionString = expectedConnectionString;
Assert.equal(1, onChangeCalled, "OnCfgChange was called");
this.clock.tick(1);
Assert.equal(2, onChangeCalled, "OnCfgChange was not called");
Assert.equal(3, onChangeCalled, "OnCfgChange was called again");
Assert.equal("newIkey", config.instrumentationKey);

//Remove the handler
handler.rm();
}
});


this.testCaseAsync({
name: "Init: init with cs promise",
stepDelay: 100,
useFakeTimers: true,
steps: [() => {

// unload previous one first
let oriInst = this._ai;
if (oriInst && oriInst.unload) {
// force unload
oriInst.unload(false);
}

this._config = this._getTestConfig(this._sessionPrefix);
let csPromise = createAsyncResolvedPromise("InstrumentationKey=testIkey;ingestionendpoint=testUrl");
this._config.connectionString = csPromise;
this._config.initTimeOut= 80000;
this._ctx.csPromise = csPromise;


let init = new ApplicationInsights(this._config);
this._ai = init;
let config = this._ai.config;


}].concat(PollingAssert.createPollingAssert(() => {
let csPromise = this._ctx.csPromise;
let config = this._ai.config;
let ikey = config.instrumentationKey;

if (csPromise.state === "resolved" && isString(ikey)) {
Assert.equal("testIkey", config.instrumentationKey, "ikey should be set");
Assert.equal("testUrl/v2/track", config.endpointUrl ,"endpoint shoule be set");
let sender = this._ai.getPlugin("AppInsightsChannelPlugin").plugin;
let senderConfig = sender["_senderConfig"] as ISenderConfig;
let senderIkey = senderConfig.instrumentationKey;
Assert.equal("testIkey", senderIkey, "sender ikey is set from connection string");
let senderUrl = senderConfig.endpointUrl;
Assert.equal("testUrl/v2/track", senderUrl, "sender endpoint url is set from connection string");

return true;
}
return false;
}, "Wait for promise response" + new Date().toISOString(), 60, 1000) as any)
});
}

public addApiTests(): void {
Expand Down
14 changes: 10 additions & 4 deletions AISKULight/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,24 @@ import {
ITelemetryInitializerHandler, ITelemetryItem, ITelemetryPlugin, ITelemetryUnloadState, IUnloadHook, UnloadHandler, WatcherFunction,
cfgDfValidate, createDynamicConfig, onConfigChange, proxyFunctions
} from "@microsoft/applicationinsights-core-js";
import { IPromise, createAsyncPromise, doAwaitResponse } from "@nevware21/ts-async";
import { IPromise, createSyncPromise, doAwaitResponse } from "@nevware21/ts-async";
import { isNullOrUndefined, isPromiseLike, isString, objDefine, throwError } from "@nevware21/ts-utils";

const UNDEFINED_VALUE: undefined = undefined;
const defaultConfigValues: IConfigDefaults<IConfiguration> = {
diagnosticLogInterval: cfgDfValidate(_chkDiagLevel, 10000)
diagnosticLogInterval: cfgDfValidate(_chkDiagLevel, 10000),
connectionString: UNDEFINED_VALUE,
endpointUrl: UNDEFINED_VALUE,
instrumentationKey: UNDEFINED_VALUE,
extensionConfig: {}
};

function _chkDiagLevel(value: number) {
// Make sure we have a value > 0
return value && value > 0;
}


/**
* @export
* @class ApplicationInsights
Expand Down Expand Up @@ -80,7 +86,7 @@ export class ApplicationInsights {
let configCs = _config.connectionString;

if (isPromiseLike(configCs)) {
let ikeyPromise = createAsyncPromise<string>((resolve, reject) => {
let ikeyPromise = createSyncPromise<string>((resolve, reject) => {
doAwaitResponse(configCs, (res) => {
let curCs = res.value;
let ikey = _config.instrumentationKey;
Expand All @@ -95,7 +101,7 @@ export class ApplicationInsights {

});

let urlPromise = createAsyncPromise<string>((resolve, reject) => {
let urlPromise = createSyncPromise<string>((resolve, reject) => {
doAwaitResponse(configCs, (res) => {
let curCs = res.value;
let url = _config.endpointUrl;
Expand Down
22 changes: 10 additions & 12 deletions channels/applicationinsights-channel-js/src/Sender.ts
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,15 @@ export class Sender extends BaseTelemetryPlugin implements IChannelControls {
}
});

// Only update the endpoint if the original config !== the current config
// This is so any redirect endpointUrl is not overwritten
if (_orgEndpointUrl !== senderConfig.endpointUrl) {
if (_orgEndpointUrl) {
// TODO: add doc to remind users to flush before changing endpoint, otherwise all unsent payload will be sent to new endpoint
}
_endpointUrl = _orgEndpointUrl = senderConfig.endpointUrl;
}

// or is not string
if (core.activeStatus() === ActiveStatus.PENDING) {
// waiting for core promises to be resolved
Expand All @@ -291,18 +300,7 @@ export class Sender extends BaseTelemetryPlugin implements IChannelControls {
} else if (core.activeStatus() === ActiveStatus.ACTIVE) {
// core status changed from pending to other status
_self.resume();

}



// Only update the endpoint if the original config !== the current config
// This is so any redirect endpointUrl is not overwritten
if (_orgEndpointUrl !== senderConfig.endpointUrl) {
if (_orgEndpointUrl) {
// TODO: add doc to remind users to flush before changing endpoint, otherwise all unsent payload will be sent to new endpoint
}
_endpointUrl = _orgEndpointUrl = senderConfig.endpointUrl;

}

if (_customHeaders && _customHeaders !== senderConfig.customHeaders) {
Expand Down
Loading