Skip to content

Commit

Permalink
[Main][Task]27923018: Post Channel getOfflineSupport should set corre…
Browse files Browse the repository at this point in the history
…ct headers and url based on payload data (#2338)

* fix 1ds offline support

* update

* update

* update

* update
  • Loading branch information
Karlie-777 committed May 6, 2024
1 parent 3af1dae commit 8d2c416
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 16 deletions.
64 changes: 61 additions & 3 deletions channels/1ds-post-js/src/HttpManager.ts
Expand Up @@ -10,7 +10,7 @@ import {
_IInternalXhrOverride, _ISendPostMgrConfig, _ISenderOnComplete, _eExtendedInternalMessageId, _eInternalMessageId, _getAllResponseHeaders,
_throwInternal, _warnToConsole, arrForEach, dateNow, doPerf, dumpObj, eLoggingSeverity, extend, getCommonSchemaMetaData, getNavigator,
getResponseText, getTime, hasOwnProperty, isBeaconsSupported, isFetchSupported, isNullOrUndefined, isReactNative, isUndefined,
isValueAssigned, objForEachKey, objKeys, onConfigChange, prependTransports, strUndefined
isValueAssigned, objForEachKey, objKeys, onConfigChange, optimizeObject, prependTransports, strUndefined
} from "@microsoft/1ds-core-js";
import { arrAppend } from "@nevware21/ts-utils";
import { BatchNotificationAction, BatchNotificationActions } from "./BatchNotificationActions";
Expand Down Expand Up @@ -331,9 +331,55 @@ export class HttpManager {
}

_self.getOfflineRequestDetails = () => {
return null;
}

_self.createOneDSPayload = (evts: ITelemetryItem[], optimize?: boolean) => {
try {
let payload = _serializer && _serializer.createPayload(0, false, false, false, SendRequestReason.NormalSchedule, EventSendType.Batched);
return _buildRequestDetails(payload, _useHeaders);
// TODO: optimize
let theBatches: EventBatch[] = [];
// create a eventBatch for each event
arrForEach(evts, (evt) => {
if (optimize) {
evt = optimizeObject(evt)
}
let batch = EventBatch.create(evt.iKey, [evt]);
theBatches.push(batch);
})

let thePayload: ISerializedPayload = null;

while (theBatches.length > 0 && _serializer) {
let theBatch = theBatches.shift();
if (theBatch && theBatch.count() > 0) {
thePayload = thePayload || _serializer.createPayload(0, false, false, false, SendRequestReason.NormalSchedule, EventSendType.Batched);
_serializer.appendPayload(thePayload, theBatch, maxEventsPerBatch)
}
}

let requestDetails = _buildRequestDetails(thePayload, _useHeaders);

let payloadData: IPayloadData = {
data: thePayload.payloadBlob,
urlString: requestDetails.url,
headers: requestDetails.hdrs,
timeout: _xhrTimeout,
disableXhrSync: _disableXhrSync,
disableFetchKeepAlive: _disableFetchKeepAlive
};

// Only automatically add the following headers if already sending headers and we are not attempting to avoid an options call
if (_useHeaders) {
if (!_hasHeader(payloadData.headers, STR_CACHE_CONTROL)) {
payloadData.headers[STR_CACHE_CONTROL] = DEFAULT_CACHE_CONTROL;
}

if (!_hasHeader(payloadData.headers, STR_CONTENT_TYPE_HEADER)) {
payloadData.headers[STR_CONTENT_TYPE_HEADER] = DEFAULT_CONTENT_TYPE;
}
}

return payloadData;

} catch (e) {
// eslint-disable-next-line no-empty
Expand All @@ -342,6 +388,8 @@ export class HttpManager {
return null;
}



// Special internal method to allow the DebugPlugin to hook embedded objects
function _getSenderInterface(transports: TransportType[], syncSupport: boolean): _IInternalXhrOverride {
try {
Expand Down Expand Up @@ -1355,4 +1403,14 @@ export class HttpManager {
// @DynamicProtoStub - DO NOT add any code as this will be removed during packaging
return null;
}

/**
* Create payload data
* @param evts telemetry events
* @returns payload
*/
public createOneDSPayload(evts?: ITelemetryItem[], optimize?: boolean): IPayloadData {
// @DynamicProtoStub - DO NOT add any code as this will be removed during packaging
return null;
}
}
14 changes: 8 additions & 6 deletions channels/1ds-post-js/src/PostChannel.ts
Expand Up @@ -236,7 +236,7 @@ export class PostChannel extends BaseTelemetryPlugin implements IChannelControls
_self.getOfflineSupport = () => {
try {
let details = _httpManager && _httpManager.getOfflineRequestDetails();
if (details) {
if (_httpManager) {
return {
getUrl: () => {
return details.url
Expand All @@ -247,11 +247,13 @@ export class PostChannel extends BaseTelemetryPlugin implements IChannelControls
return !_disableTelemetry;
},
createPayload: (evt) => {
return {
urlString: details.url,
headers: details.hdrs,
data: evt
} as IPayloadData;
return null;
},
createOneDSPayload: (evts: ITelemetryItem[]) => {
if (_httpManager.createOneDSPayload) {
return _httpManager.createOneDSPayload(evts, _optimizeObject);
}

}
} as IInternalOfflineSupport;

Expand Down
28 changes: 24 additions & 4 deletions channels/1ds-post-js/test/Unit/src/HttpManagerTest.ts
Expand Up @@ -222,10 +222,30 @@ export class HttpManagerTest extends AITestClass {
QUnit.assert.equal(evtStr, `{"name":"testEvent","iKey":"o:testKey","data":{"baseData":{}}}`,"Event should be serialized");

QUnit.assert.ok(manager.getOfflineRequestDetails, "request details function should exist");
let details = manager.getOfflineRequestDetails();
QUnit.assert.equal(details.url, "testEndpoint?cors=true&content-type=application/x-json-stream&w=0", "get expected Url");
QUnit.assert.ok(details.hdrs, "get headers Url");
QUnit.assert.ok(details.useHdrs, "should use headers");
QUnit.assert.equal(manager.getOfflineRequestDetails(), null, "request details function should return null for 1ds");
let details = manager.createOneDSPayload([evt]);
let headers = details.headers || {};
let apiKey = headers["apikey"];
QUnit.assert.equal(apiKey, "testKey-123", "should get expected api key");
QUnit.assert.equal(details.data, `{"name":"testEvent","iKey":"o:testKey","data":{"baseData":{}}}`, "should return expected data");

let evt1 = this._createEvent();
evt1.iKey = "testKey-12345";
evt1.name = "testEvent1";
details = manager.createOneDSPayload([evt, evt1]);
headers = details.headers || {};
apiKey = headers["apikey"];
QUnit.assert.equal(apiKey, "testKey-123,testKey-12345", "should get expected api keys test1");
QUnit.assert.equal(details.data, `{"name":"testEvent","iKey":"o:testKey","data":{"baseData":{}}}\n{"name":"testEvent1","iKey":"o:testKey","data":{"baseData":{}}}`, "should return expected data test1");

let evt2 = this._createEvent();
evt2.iKey = "testKey-123";
evt2.name = "testEvent2";
details = manager.createOneDSPayload([evt, evt2]);
headers = details.headers || {};
apiKey = headers["apikey"];
QUnit.assert.equal(apiKey, "testKey-123", "should get expected api keys test2");
QUnit.assert.equal(details.data, `{"name":"testEvent","iKey":"o:testKey","data":{"baseData":{}}}\n{"name":"testEvent2","iKey":"o:testKey","data":{"baseData":{}}}`, "should return expected data test2");

}
});
Expand Down
5 changes: 3 additions & 2 deletions channels/1ds-post-js/test/Unit/src/PostChannelTest.ts
Expand Up @@ -311,10 +311,11 @@ export class PostChannelTest extends AITestClass {
QUnit.assert.equal(offlineSupport.shouldProcess(event), true, "should process");

QUnit.assert.ok(offlineSupport.createPayload, "createPayload should exit");
let details = offlineSupport.createPayload("test");
QUnit.assert.equal(offlineSupport.createPayload("test"), null, "createPayload should return null now");
let details = offlineSupport.createOneDSPayload([event]);
QUnit.assert.equal(details.urlString, "https://testEndpoint?cors=true&content-type=application/x-json-stream&w=0", "get expected Url");
QUnit.assert.ok(details.headers, "get headers Url");
QUnit.assert.equal(details.data, "test", "get expected data");
QUnit.assert.equal(details.data, expectedStr, "get expected data");

this.core.config.extensionConfig = this.core.config.extensionConfig || {};
this.core.config.extensionConfig[postId].disableTelemetry = true;
Expand Down
13 changes: 12 additions & 1 deletion channels/offline-channel-js/src/OfflineChannel.ts
Expand Up @@ -347,8 +347,19 @@ export class OfflineChannel extends BaseTelemetryPlugin implements IChannelContr
let sentItems = evts.slice(0, idx + 1);

_inMemoBatch = _inMemoBatch.createNew(_endpoint, inMemo.getItems().slice(idx + 1), _evtsLimitInMemo);

let payloadData: IStorageTelemetryItem = null;
if (_offineSupport && _offineSupport.createOneDSPayload) {
payloadData = _offineSupport.createOneDSPayload(sentItems);
if (payloadData) {
payloadData.criticalCnt = criticalCnt;
}

} else {
payloadData = _constructPayloadData(payloadArr, criticalCnt);
}

let payloadData = _constructPayloadData(payloadArr, criticalCnt);

let callback: OfflineBatchStoreCallback = (res) => {
if (!res || !res.state) {
return null;
Expand Down
Expand Up @@ -47,6 +47,13 @@ export interface IInternalOfflineSupport {
*/
shouldProcess?: (evt: ITelemetryItem) => boolean;

/**
* Create 1ds payload data
* @param evts ITelemetryItems
* @returns IPayloadData
*/
createOneDSPayload?: (evts: ITelemetryItem[]) => IPayloadData;

}

/**
Expand Down

0 comments on commit 8d2c416

Please sign in to comment.