Skip to content

[FSSDK-9362] chore: ODP code & comment adjustments #827

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 30, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,7 @@ export class NotificationRegistry {
* @param logger Logger to be used for the corresponding notification center
* @returns {NotificationCenter | undefined} a notification center instance for ODP Manager if a valid SDK Key is provided, otherwise undefined
*/
public static getNotificationCenter(
sdkKey?: string,
logger: LogHandler = getLogger()
): NotificationCenter | undefined {
static getNotificationCenter(sdkKey?: string, logger: LogHandler = getLogger()): NotificationCenter | undefined {
if (!sdkKey) {
logger.log(LogLevel.ERROR, 'No SDK key provided to getNotificationCenter.');
return undefined;
Expand All @@ -54,7 +51,7 @@ export class NotificationRegistry {
return notificationCenter;
}

public static removeNotificationCenter(sdkKey?: string): void {
static removeNotificationCenter(sdkKey?: string): void {
if (!sdkKey) {
return;
}
Expand Down
15 changes: 0 additions & 15 deletions packages/optimizely-sdk/lib/core/odp/index.ts

This file was deleted.

12 changes: 6 additions & 6 deletions packages/optimizely-sdk/lib/core/odp/odp_config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export class OdpConfig {
* Getter to retrieve the ODP server host
* @public
*/
public get apiHost(): string {
get apiHost(): string {
return this._apiHost;
}

Expand All @@ -41,7 +41,7 @@ export class OdpConfig {
* Getter to retrieve the ODP API key
* @public
*/
public get apiKey(): string {
get apiKey(): string {
return this._apiKey;
}

Expand All @@ -55,7 +55,7 @@ export class OdpConfig {
* Getter for ODP segments to check
* @public
*/
public get segmentsToCheck(): string[] {
get segmentsToCheck(): string[] {
return this._segmentsToCheck;
}

Expand All @@ -70,7 +70,7 @@ export class OdpConfig {
* @param {OdpConfig} config New ODP Config to potentially update self with
* @returns true if configuration was updated successfully
*/
public update(config: OdpConfig): boolean {
update(config: OdpConfig): boolean {
if (this.equals(config)) {
return false;
} else {
Expand All @@ -85,7 +85,7 @@ export class OdpConfig {
/**
* Determines if ODP configuration has the minimum amount of information
*/
public isReady(): boolean {
isReady(): boolean {
return !!this._apiKey && !!this._apiHost;
}

Expand All @@ -94,7 +94,7 @@ export class OdpConfig {
* @param configToCompare ODP Configuration to check self against for equality
* @returns Boolean based on if the current ODP Config is equivalent to the incoming ODP Config
*/
public equals(configToCompare: OdpConfig): boolean {
equals(configToCompare: OdpConfig): boolean {
return (
this._apiHost === configToCompare._apiHost &&
this._apiKey === configToCompare._apiKey &&
Expand Down
10 changes: 5 additions & 5 deletions packages/optimizely-sdk/lib/core/odp/odp_event.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2022, Optimizely
* Copyright 2022-2023, Optimizely
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -18,22 +18,22 @@ export class OdpEvent {
/**
* Type of event (typically "fullstack")
*/
public type: string;
type: string;

/**
* Subcategory of the event type
*/
public action: string;
action: string;

/**
* Key-value map of user identifiers
*/
public identifiers: Map<string, string>;
identifiers: Map<string, string>;

/**
* Event data in a key-value map
*/
public data: Map<string, unknown>;
data: Map<string, unknown>;

/**
* Event to be sent and stored in the Optimizely Data Platform
Expand Down
29 changes: 21 additions & 8 deletions packages/optimizely-sdk/lib/core/odp/odp_event_api_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,16 @@ export interface IOdpEventApiManager {
* Concrete implementation for accessing the ODP REST API
*/
export abstract class OdpEventApiManager implements IOdpEventApiManager {
/**
* Handler for recording execution logs
* @private
*/
private readonly logger: LogHandler;

/**
* Handler for making external HTTP/S requests
* @private
*/
private readonly requestHandler: RequestHandler;

/**
Expand All @@ -44,7 +53,7 @@ export abstract class OdpEventApiManager implements IOdpEventApiManager {
this.logger = logger;
}

public getLogger(): LogHandler {
getLogger(): LogHandler {
return this.logger;
}

Expand All @@ -55,7 +64,7 @@ export abstract class OdpEventApiManager implements IOdpEventApiManager {
* @param events ODP events to send
* @returns Retry is true - if network or server error (5xx), otherwise false
*/
public async sendEvents(apiKey: string, apiHost: string, events: OdpEvent[]): Promise<boolean> {
async sendEvents(apiKey: string, apiHost: string, events: OdpEvent[]): Promise<boolean> {
let shouldRetry = false;

if (!apiKey || !apiHost) {
Expand Down Expand Up @@ -101,10 +110,14 @@ export abstract class OdpEventApiManager implements IOdpEventApiManager {

protected abstract shouldSendEvents(events: OdpEvent[]): boolean;

protected abstract generateRequestData(apiHost: string, apiKey: string, events: OdpEvent[]): {
method: string,
endpoint: string,
headers: {[key: string]: string},
data: string,
}
protected abstract generateRequestData(
apiHost: string,
apiKey: string,
events: OdpEvent[]
): {
method: string;
endpoint: string;
headers: { [key: string]: string };
data: string;
};
}
30 changes: 20 additions & 10 deletions packages/optimizely-sdk/lib/core/odp/odp_event_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,59 +61,69 @@ export abstract class OdpEventManager implements IOdpEventManager {
/**
* Current state of the event processor
*/
public state: STATE = STATE.STOPPED;
state: STATE = STATE.STOPPED;

/**
* Queue for holding all events to be eventually dispatched
* @protected
*/
protected queue = new Array<OdpEvent>();

/**
* Identifier of the currently running timeout so clearCurrentTimeout() can be called
* @private
*/
private timeoutId?: NodeJS.Timeout | number;

/**
* ODP configuration settings in used
* ODP configuration settings for identifying the target API and segments
* @private
*/
private odpConfig: OdpConfig;

/**
* REST API Manager used to send the events
* @private
*/
private readonly apiManager: IOdpEventApiManager;

/**
* Handler for recording execution logs
* @private
*/
private readonly logger: LogHandler;

/**
* Maximum queue size
* @protected
*/
protected queueSize!: number;

/**
* Maximum number of events to process at once. Ignored in browser context
* @protected
*/
protected batchSize!: number;

/**
* Milliseconds between setTimeout() to process new batches. Ignored in browser context
* @protected
*/
protected flushInterval!: number;

/**
* Type of execution context eg node, js, react
* @private
*/
private readonly clientEngine: string;

/**
* Version of the client being used
* @private
*/
private readonly clientVersion: string;

public constructor({
constructor({
odpConfig,
apiManager,
logger,
Expand Down Expand Up @@ -151,21 +161,21 @@ export abstract class OdpEventManager implements IOdpEventManager {
* Update ODP configuration settings.
* @param newConfig New configuration to apply
*/
public updateSettings(newConfig: OdpConfig): void {
updateSettings(newConfig: OdpConfig): void {
this.odpConfig = newConfig;
}

/**
* Cleans up all pending events; occurs every time the ODP Config is updated.
*/
public flush(): void {
flush(): void {
this.processQueue(true);
}

/**
* Start processing events in the queue
*/
public start(): void {
start(): void {
this.state = STATE.RUNNING;

this.setNewTimeout();
Expand All @@ -174,7 +184,7 @@ export abstract class OdpEventManager implements IOdpEventManager {
/**
* Drain the queue sending all remaining events in batches then stop processing
*/
public async stop(): Promise<void> {
async stop(): Promise<void> {
this.logger.log(LogLevel.DEBUG, 'Stop requested.');

await this.processQueue(true);
Expand All @@ -187,7 +197,7 @@ export abstract class OdpEventManager implements IOdpEventManager {
* Register a new visitor user id (VUID) in ODP
* @param vuid Visitor User ID to send
*/
public registerVuid(vuid: string): void {
registerVuid(vuid: string): void {
const identifiers = new Map<string, string>();
identifiers.set(ODP_USER_KEY.VUID, vuid);

Expand All @@ -200,7 +210,7 @@ export abstract class OdpEventManager implements IOdpEventManager {
* @param {string} userId (Optional) Full-stack User ID
* @param {string} vuid (Optional) Visitor User ID
*/
public identifyUser(userId?: string, vuid?: string): void {
identifyUser(userId?: string, vuid?: string): void {
const identifiers = new Map<string, string>();
if (!userId && !vuid) {
this.logger.log(LogLevel.ERROR, ERROR_MESSAGES.ODP_SEND_EVENT_FAILED_UID_MISSING);
Expand All @@ -223,7 +233,7 @@ export abstract class OdpEventManager implements IOdpEventManager {
* Send an event to ODP via dispatch queue
* @param event ODP Event to forward
*/
public sendEvent(event: OdpEvent): void {
sendEvent(event: OdpEvent): void {
if (invalidOdpDataFound(event.data)) {
this.logger.log(LogLevel.ERROR, 'Event data found to be invalid.');
} else {
Expand Down
43 changes: 40 additions & 3 deletions packages/optimizely-sdk/lib/core/odp/odp_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,27 +27,47 @@ import { OptimizelySegmentOption } from './optimizely_segment_option';
import { invalidOdpDataFound } from './odp_utils';
import { OdpEvent } from './odp_event';

/**
* Manager for handling internal all business logic related to
* Optimizely Data Platform (ODP) / Advanced Audience Targeting (AAT)
*/
export interface IOdpManager {
initPromise?: Promise<void>;

enabled: boolean;

segmentManager: IOdpSegmentManager | undefined;

eventManager: IOdpEventManager | undefined;

updateSettings({ apiKey, apiHost, segmentsToCheck }: OdpConfig): boolean;

close(): void;

fetchQualifiedSegments(userId: string, options?: Array<OptimizelySegmentOption>): Promise<string[] | null>;

identifyUser(userId?: string, vuid?: string): void;

sendEvent({ type, action, identifiers, data }: OdpEvent): void;

isVuidEnabled(): boolean;

getVuid(): string | undefined;
}

/**
* Orchestrates segments manager, event manager, and ODP configuration
*/
export abstract class OdpManager implements IOdpManager {
/**
* Promise that returns when the OdpManager is finished initializing
*/
initPromise?: Promise<void>;

/**
* Switch to enable/disable ODP Manager functionality
*/
enabled = true;
logger: LogHandler = getLogger();
odpConfig: OdpConfig = new OdpConfig();

/**
* ODP Segment Manager which provides an interface to the remote ODP server (GraphQL API) for audience segments mapping.
Expand All @@ -61,7 +81,18 @@ export abstract class OdpManager implements IOdpManager {
*/
eventManager: IOdpEventManager | undefined;

constructor() {}
/**
* Handler for recording execution logs
* @protected
*/
protected logger: LogHandler = getLogger(); // TODO: Consider making private and moving instantiation to constructor

/**
* ODP configuration settings for identifying the target API and segments
*/
odpConfig: OdpConfig = new OdpConfig(); // TODO: Consider making private and adding public accessors

constructor() {} // TODO: Consider accepting logger as a parameter and initializing it in constructor instead

/**
* Provides a method to update ODP Manager's ODP Config API Key, API Host, and Audience Segments
Expand Down Expand Up @@ -195,7 +226,13 @@ export abstract class OdpManager implements IOdpManager {
this.eventManager.sendEvent(new OdpEvent(mType, action, identifiers, data));
}

/**
* Identifies if the VUID feature is enabled
*/
abstract isVuidEnabled(): boolean;

/**
* Returns VUID value if it exists
*/
abstract getVuid(): string | undefined;
}
Loading