Interface SecondaryDataSessionInterfaceInfo

The SecondaryDataSessionInterfaceInfo interface is used to create secondary sessions of a given DataSessionInterface.

This is an opaque readonly object that may be streamed and read. Any modification of this object will result in undefined behavior. The SecondaryDataSessionInterfaceInfo is created with DataSessionInterface.requestNewSecondaryDataSession and used with DataSessionInterface.openSecondaryDataSession in replacement of DataSessionInterface.openDataSession.

There is only a finite number of secondary data session that can be created at the same time, ths it is necessary to call DataSessionInterface.unregisterSecondaryDataSession to notify the primary DataSessionInterface that this secondary data session is no longer in use (there is no internal signaling). It will be necessary to call DataSessionInterface.setTokenValues on a regular basis to notify the secondary DataSessionInterface of bearer modifications (use DataSessionInterfaceSignal.TokenUpdated for this matter).

/** 
* Sample to illustrate the use of the primary/secondary session mechanism of DirectorySessionInterface and DataSessionInterface.
*/
import {
InfiniteCacheFactory, DirectorySessionFactory,
InfiniteCacheInterface, DirectorySessionInterface,
DataSessionInterface,
DataSessionInterfaceSignal, DirectorySessionInterfaceSignal,
SecondaryDirectorySessionInterfaceInfo,
SecondaryDataSessionInterfaceInfo,
AuthenticationGetURLResult,
} from 'generated_files/documentation/appinfiniteapi';

// this sample holds the code to be use in the primary tab (primaryCode)
// and in the secondary tab (secondaryCode)

// a callback to receive messages
type tMessageHandler = (pMessage: any) => void;

// we suppose that there exists a message system
let sendMessage : (pMessage: any) => void;

// we suppose that we can register a handler to receive messages
let registerMessageHandler : (pMessageHandler: tMessageHandler) => void;

// the primary code
const primaryCode = () : void =>
{
// created previously
// this is the directory session that will server as primary session
// this DirectorySessionInterface should already be logged in
let lOriginalDirectorySession : DirectorySessionInterface;

// created previously
// this is the data session that will server as primary session
// this DataSessionInterface should already be primary session
let lOriginalDataSession : DataSessionInterface;

// create a secondary session info to init the future secondary DirectorySessionInterface
const lSecondaryDirectorySessionInfo : SecondaryDirectorySessionInterfaceInfo | undefined = lOriginalDirectorySession.requestNewSecondaryDirectorySession();
if(lSecondaryDirectorySessionInfo === undefined)
{
// output some fancy error message
console.error('secondary directory session info creation failed');
return;
}

// create a secondary session info to init the future secondary DataSessionInterface
// warning : this call will hold resources in the primary DataSessionInterface
// when the secondary data session is no longer useful
// release resources with unregisterSecondaryDataSession
// warning: there is a finite number of secondary data sessions that may be created
let lSecondaryDataSessionInfo : SecondaryDataSessionInterfaceInfo | undefined = lOriginalDataSession.requestNewSecondaryDataSession();
if(lSecondaryDataSessionInfo === undefined)
{
// output some fancy error message
console.error('secondary data session info creation failed');
return;
}

// called when the DirectorySessionInterface updates its tokens
const lDirectorySessionTokenUpdate = () : void => {
const lHttpBearer : string = lOriginalDirectorySession.getHttpBearer();
// only update tokens when the directory session is connected
if(lHttpBearer.length > 0)
{
// send the new directory session tokens to the secondary
sendMessage({
type: 'directorySessionTokens',
httpBearer: lHttpBearer,
authenticationBearer: lOriginalDirectorySession.getAuthenticationBearer(),
extendedAuthenticationBearer: lOriginalDirectorySession.getExtendedAuthenticationBearer(),
});
}
};

// called when the DataSessionInterface updates its tokens
const lDataSessionTokenUpdate = () : void => {
const lDataSessionBearer : string = lOriginalDataSession.getDataSessionBearer();
// only update tokens when the data session is connected
if(lDataSessionBearer.length > 0)
{
// send the new data session tokens to the secondary session
sendMessage({
type: 'dataSessionTokens',
dataSessionBearer: lDataSessionBearer,
extendedDataSessionBearer: lOriginalDataSession.getExtendedDataSessionBearer(),
});
}
};

// message callback, receive messages from the secondary session
const onMessage : tMessageHandler = (pMessage : any) : void =>
{
switch(pMessage.type)
{
// cleanup the secondary session resources
case 'dataSessionCleanup':
if(lSecondaryDataSessionInfo !== undefined)
{
lOriginalDataSession.unregisterSecondaryDataSession(lSecondaryDataSessionInfo);
// cleanup only once
lSecondaryDataSessionInfo = undefined;
}
break;
default:
// this should not happen, we have no other message types that we may receive
console.error('Unexpected message type');
break;
}
};

// and register the token update functions on token update
lOriginalDirectorySession.addEventListener(DirectorySessionInterfaceSignal.TokenUpdated, lDirectorySessionTokenUpdate);
lOriginalDataSession.addEventListener(DataSessionInterfaceSignal.TokenUpdated, lDataSessionTokenUpdate);
// register callbacks
registerMessageHandler(onMessage);

// we are ready, send the infos to load a new secondary directory and data session
sendMessage({
type: 'init',
directorySession: lSecondaryDirectorySessionInfo,
dataSession: lSecondaryDataSessionInfo,
// build id is required to create a data session on the correct build
buildId: lOriginalDataSession.getBuildId()
});
};

// the secondary session code
const secondaryCode = () : void =>
{
// create a directory session
const sDirectoryUrl : string = 'https://my_directory:443/directory';
// before connection, this is a "normal" one
const lSecondaryDirectorySession : DirectorySessionInterface = DirectorySessionFactory.CreateDirectorySession(sDirectoryUrl);
// Create a cache to avoid requesting heavy data from the server if data has been retrieved already
const lCache: InfiniteCacheInterface = InfiniteCacheFactory.CreateInfiniteCache();
// the new data session
// we cannot create it right now, we must wait for secondary session info and directory session login
let lSecondaryDataSession : DataSessionInterface;
// hold the open secondary session info for future call
let lSecondaryDataSessionInterfaceInfo : SecondaryDataSessionInterfaceInfo;
// the build id we will be connected to
let lDataSessionBuildId : string = '';

// Success callback on DirectorySessionInterface login
const onLoginSuccess = () : void => {
// weird, we should have a build id at this time
if(lDataSessionBuildId.length === 0)
{
// and output some message if the data session creation failed
console.error('data session creation failed, empty build id');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
return;
}
// actually create the DataSessionInterface
lSecondaryDataSession = lSecondaryDirectorySession.createDataSession(lDataSessionBuildId, lCache);
if(lSecondaryDataSession === undefined)
{
// and output some message if the data session creation failed
console.error('data session creation failed');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
return;
}
// open it in secondary session mode
if(!lSecondaryDataSession.openSecondaryDataSession(lSecondaryDataSessionInterfaceInfo))
{
// and output some message if the data session opening failed
console.error('secondary data session opening failed');
// get rid of data
lSecondaryDataSession.dispose();
lSecondaryDataSession = undefined;
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
}
// and then we must wait for the DataSessionInterface to be connected
};

// message callback, receive secondary sessions info and tokens
const onMessage : tMessageHandler = (pMessage : any) : void =>
{
switch(pMessage.type)
{
// secondary sessions infos
case 'init':
{
lSecondaryDataSessionInterfaceInfo = pMessage.dataSession;
lDataSessionBuildId = pMessage.buildId;
const lResult : AuthenticationGetURLResult = lSecondaryDirectorySession.openSecondaryDirectorySession(pMessage.directorySession);
if(lResult !== AuthenticationGetURLResult.AuthenticationPending)
{
// and output some message if the data session opening failed
console.error('directory session opening failed');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
}
break;
}
case 'directorySessionTokens':
{
// do nothing if the directory session is not connected
if(!lSecondaryDirectorySession.isAuthenticated())
{
return;
}
// and update the tokens
const lResult : boolean = lSecondaryDirectorySession.setTokenValues(pMessage.httpBearer, pMessage.authenticationBearer, pMessage.extendedAuthenticationBearer);
if(!lResult)
{
// and output some message if the token update failed
console.error('set token values failed');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
}
break;
}
case 'dataSessionTokens':
{
// do nothing if the data session is not connected nor created
if(lSecondaryDataSession === undefined || !lSecondaryDataSession.isConnected())
{
return;
}
// and update the tokens
const lResult : boolean = lSecondaryDataSession.setTokenValues(pMessage.dataSessionBearer, pMessage.extendedDataSessionBearer);
if(!lResult)
{
// and output some message if the token update failed
console.error('set token values failed');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
}
break;
}
default:
// this should not happen, we have no other message types that we may receive
console.error('Unexpected message type');
break;
}
};

// register callbacks
lSecondaryDirectorySession.addEventListener(DirectorySessionInterfaceSignal.LoginSuccess, onLoginSuccess);
registerMessageHandler(onMessage);
};

// in the primary part
primaryCode();

// in the secondary part
secondaryCode();

or asynchronously :
/** 
* Sample to illustrate the asynchronous use of the primary/secondary session mechanism of DirectorySessionInterface
* and DataSessionInterface.
*/
import {
InfiniteCacheFactory, DirectorySessionFactory,
InfiniteCacheInterface, DirectorySessionInterface,
DataSessionInterface,
DataSessionInterfaceSignal, DirectorySessionInterfaceSignal,
SecondaryDirectorySessionInterfaceInfo,
SecondaryDataSessionInterfaceInfo,
AsyncDirectorySessionWaitForLoadedResult,
AsyncDirectorySessionWaitForLoadedResultReason,
AsyncDataSessionInterfaceOpenResult,
} from 'generated_files/documentation/appinfiniteapi';

// this sample holds the code to be use in the primary tab (primaryCode)
// and in the secondary tab (secondaryCode)

// a callback to receive messages
type tMessageHandler = (pMessage: any) => void;

// we suppose that there exists a message system
let sendMessage : (pMessage: any) => void;

// we suppose that we can register a handler to receive messages
let registerMessageHandler : (pMessageHandler: tMessageHandler) => void;

// the primary code
const primaryCode = () : void =>
{
// created previously
// this is the directory session that will server as primary session
// this DirectorySessionInterface should already be logged in
let lOriginalDirectorySession : DirectorySessionInterface;

// created previously
// this is the data session that will server as primary session
// this DataSessionInterface should already be connected
let lOriginalDataSession : DataSessionInterface;

// create a secondary session info to init the future secondary DirectorySessionInterface
const lSecondaryDirectorySessionInfo : SecondaryDirectorySessionInterfaceInfo | undefined = lOriginalDirectorySession.requestNewSecondaryDirectorySession();
if(lSecondaryDirectorySessionInfo === undefined)
{
// output some fancy error message
console.error('secondary directory session info creation failed');
return;
}

// create a secondary data session info to init the future secondary DataSessionInterface
// warning : this call will hold resources in the primary DataSessionInterface
// when the secondary data session is no longer useful
// release resources with unregisterSecondaryDataSession
// warning: there is a finite number of secondary data sessions that may be created
let lSecondaryDataSessionInfo : SecondaryDataSessionInterfaceInfo | undefined = lOriginalDataSession.requestNewSecondaryDataSession();
if(lSecondaryDataSessionInfo === undefined)
{
// output some fancy error message
console.error('secondary data session info creation failed');
return;
}

// called when the DirectorySessionInterface updates its tokens
const lDirectorySessionTokenUpdate = () : void => {
const lHttpBearer : string = lOriginalDirectorySession.getHttpBearer();
// only update tokens when the directory session is connected
if(lHttpBearer.length > 0)
{
// send the new directory session tokens to the secondary session
sendMessage({
type: 'directorySessionTokens',
httpBearer: lHttpBearer,
authenticationBearer: lOriginalDirectorySession.getAuthenticationBearer(),
extendedAuthenticationBearer: lOriginalDirectorySession.getExtendedAuthenticationBearer(),
});
}
};

// called when the DataSessionInterface updates its tokens
const lDataSessionTokenUpdate = () : void => {
const lDataSessionBearer : string = lOriginalDataSession.getDataSessionBearer();
// only update tokens when the data session is connected
if(lDataSessionBearer.length > 0)
{
// send the new data session tokens to the secondary session
sendMessage({
type: 'dataSessionTokens',
dataSessionBearer: lDataSessionBearer,
extendedDataSessionBearer: lOriginalDataSession.getExtendedDataSessionBearer(),
});
}
};

// message callback, receive messages from the secondary session
const onMessage : tMessageHandler = (pMessage : any) : void =>
{
switch(pMessage.type)
{
// cleanup the secondary data session resources
case 'dataSessionCleanup':
if(lSecondaryDataSessionInfo !== undefined)
{
lOriginalDataSession.unregisterSecondaryDataSession(lSecondaryDataSessionInfo);
// cleanup only once
lSecondaryDataSessionInfo = undefined;
}
break;
default:
// this should not happen, we have no other message types that we may receive
console.error('Unexpected message type');
break;
}
};

// and register the token update functions on token update
lOriginalDirectorySession.addEventListener(DirectorySessionInterfaceSignal.TokenUpdated, lDirectorySessionTokenUpdate);
lOriginalDataSession.addEventListener(DataSessionInterfaceSignal.TokenUpdated, lDataSessionTokenUpdate);
// register callbacks
registerMessageHandler(onMessage);

// we are ready, send the infos to load a new secondary directory and data session
sendMessage({
type: 'init',
directorySession: lSecondaryDirectorySessionInfo,
dataSession: lSecondaryDataSessionInfo,
// build id is required to create a data session on the correct build
buildId: lOriginalDataSession.getBuildId()
});
};

// the secondary session code
const secondaryCode = () : void =>
{
// create a directory session
const sDirectoryUrl : string = 'https://my_directory:443/directory';
// before connection, this is a "normal" one
const lSecondaryDirectorySession : DirectorySessionInterface = DirectorySessionFactory.CreateDirectorySession(sDirectoryUrl);
// Create a cache to avoid requesting heavy data from the server if data has been retrieved already
const lCache: InfiniteCacheInterface = InfiniteCacheFactory.CreateInfiniteCache();
// the new data session
// we cannot create it right now, we must wait for secondary session info and directory session login
let lSecondaryDataSession : DataSessionInterface;
// hold the open secondary info for future call
let lSecondaryDataSessionInterfaceInfo : SecondaryDataSessionInterfaceInfo;
// the build id we will be connected to
let lDataSessionBuildId : string = '';

// message callback, receive secondary sessions info and tokens
const onMessage : tMessageHandler = (pMessage : any) : void =>
{
switch(pMessage.type)
{
// secondary sessions infos
case 'init':
{
lSecondaryDataSessionInterfaceInfo = pMessage.dataSession;
lDataSessionBuildId = pMessage.buildId;
lSecondaryDirectorySession.asyncOpenSecondaryDirectorySession(pMessage.directorySession).then(
(pOpenResult: AsyncDirectorySessionWaitForLoadedResult) : void => {
if(pOpenResult.reason !== AsyncDirectorySessionWaitForLoadedResultReason.OpenResult_LoginSuccess)
{
// and output some message if the data session opening failed
console.error('directory session opening failed');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
return;
}
// weird, we should have a build id at this time
if(lDataSessionBuildId.length === 0)
{
// and output some message if the data session creation failed
console.error('data session creation failed, empty build id');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
return;
}
// actually create the DataSessionInterface
lSecondaryDataSession = lSecondaryDirectorySession.createDataSession(lDataSessionBuildId, lCache);
if(lSecondaryDataSession === undefined)
{
// and output some message if the data session creation failed
console.error('data session creation failed');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
return;
}
// open it in secondary session mode
lSecondaryDataSession.asyncOpenSecondaryDataSession(lSecondaryDataSessionInterfaceInfo).then(
(pDataSessionResult: AsyncDataSessionInterfaceOpenResult) : void =>
{
if(pDataSessionResult !== AsyncDataSessionInterfaceOpenResult.OpenResult_Success)
{
// and output some message if the data session opening failed
console.error('secondary data session opening failed');
// get rid of data
lSecondaryDataSession.dispose();
lSecondaryDataSession = undefined;
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
}
// and do some fancy things there :)
// we are connected correctly
}
);
}
);
break;
}
case 'directorySessionTokens':
{
// do nothing if the directory session is not connected
if(!lSecondaryDirectorySession.isAuthenticated())
{
return;
}
// and update the tokens
const lResult : boolean = lSecondaryDirectorySession.setTokenValues(pMessage.httpBearer, pMessage.authenticationBearer, pMessage.extendedAuthenticationBearer);
if(!lResult)
{
// and output some message if the token update failed
console.error('set token values failed');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
}
break;
}
case 'dataSessionTokens':
{
// do nothing if the data session is not connected nor created
if(lSecondaryDataSession === undefined || !lSecondaryDataSession.isConnected())
{
return;
}
// and update the tokens
const lResult : boolean = lSecondaryDataSession.setTokenValues(pMessage.dataSessionBearer, pMessage.extendedDataSessionBearer);
if(!lResult)
{
// and output some message if the token update failed
console.error('set token values failed');
// and tell the primary session to get rid of the secondary session
sendMessage({ type: 'dataSessionCleanup' });
}
break;
}
default:
// this should not happen, we have no other message types that we may receive
console.error('Unexpected message type');
break;
}
};

// register callbacks
registerMessageHandler(onMessage);
};

// in the primary part
primaryCode();

// in the secondary part
secondaryCode();

The primary/secondary mechanism may be used to share the same DataSessionInterface across multiple tabs.
Sessions

interface SecondaryDataSessionInterfaceInfo {
    accesstoken: string;
    accesstokenextended?: string;
    buildproperties: any;
    data_session_heartbeat_before: number;
    endId: number;
    proxyurl: string;
    sequenceStart: number;
    sessionId: number;
    startId: number;
}

Properties

accesstoken: string

The access token of this secondary DataSessionInterface.

accesstokenextended?: string

The optional extended access token of this secondary DataSessionInterface.

buildproperties: any

The build properties of this secondary DataSessionInterface.

data_session_heartbeat_before: number

The time (in time_t) before a heartbeat may be performed for this secondary DataSessionInterface.

endId: number

The end id for backend objects created from this secondary DataSessionInterface.

proxyurl: string

The proxy url id of this secondary DataSessionInterface.

sequenceStart: number

The sequence start for backend object created from this secondary DataSessionInterface.

sessionId: number

The secondary id of this secondary DataSessionInterface.

startId: number

The start id for backend objects created from this secondary DataSessionInterface.