/* start block _extraPreContent_ */ /* end block */ //methods removed from sdk.js and added to handle new window open both for dropdowm and page menu. var topWindow; var thisIsTheTopWindow = false; var openWindowList = null; var currentEventSeqId = -1; var uid = ""; // Failover var failoverInitialized = false; var recyclePushlet = false; var isEventingConnected = false; // Current server connection variables var serverProtocol = ""; var serverAddress = ""; var serverName = ""; var serverPort = ""; var applicationContext = ""; // Failover retry variables var eventingMaxRetry = 100; var eventingCurrentRetry = 0; // Failover server list variables var failoverServerList = null; var failoverServerIndex = 0; var failoverServerRetries = 3; var failoverCurrentServerRetry = -1; // HeartBeat tiemout check variables var heartbeatTimeoutEnabled = false; var heartbeatTimeout = 7; // Heartbeat Timeout (seconds) var heartbeatTimestamp = null; var ignoreHeartbeat = true; // Heartbeat timeout will be enabled after when the first event is received var eventingActive = true; // isEventing active // ODV Failover message control var disconnectMessageSent = true; var stopRetry = false; var disconnected = false; var checkWindowsInterval = 10000; var checkWindowsID = null; var checkWindowFailCnt = 0; var maxCheckWindowFails = 3; var checkWindowErrorMsgAfterCnt = 2; var failoverRefreshReason = "FAILOVER"; /** * Connectivity globals */ var connections = [ { "type" : "-", "name" : "-", "details" : {}, "status" : "-" } ]; var hasDisconnections = false; var disconnectionWarning = false; var connectionStatusChange = false; /** * Array for storing an history of pushlet connection events */ var eventingHistory = []; // If outer window then set interval to monitor bad window references.... // for both the child and the top window // if popup window don't start timer if (window.top === window && !window.top.isUnmanagedPopup) { checkWindowsID = window.setInterval(checkWindowReferencesInterval, checkWindowsInterval); setTopWindow(); // add event handler for outerwindow closing document.ignoreLogoff = false; window.addEventListener("unload", displayUnLoad, false); // run the window reference interval with timeout 0 for rendering to catchup setTimeout(function() { checkWindowReferencesInterval(); }, 0); } /** * Object that represents an history entry */ function EventingHistoryEntry(timestamp, retryCount, serverRetryCount, eventType, URL) { this.timestamp = timestamp; this.eventType = eventType; this.retryCount = retryCount; this.serverRetryCount = serverRetryCount; this.URL = URL; } /** * Function for adding history entry */ function addEventingHistoryEntry(timestamp, retryCount, serverRetryCount, eventType, URL) { try { eventingHistory.push(new EventingHistoryEntry(timestamp, retryCount, serverRetryCount, eventType, URL)); } catch (e) { log.error("Unable to addEventingHistoryEntry: ", e); } } /** * Eventing history functions * * @param page - * page nr, or "last" * @param rowsPerPage - * Nr of rows per page */ function showEventingSummary() { var page = (arguments[0] ? (arguments[0] == "last" ? arguments[0] : (arguments[0] - 1)) : 0); var rowsPerPage = (arguments[1] ? arguments[1] : 10); var formatted = (arguments[2] ? arguments[2] : false); var initialIndex = 0; var totalPages = eventingHistory.length / rowsPerPage; if (page == "last") { page = Math.floor(totalPages); } if (eventingHistory.length > rowsPerPage && totalPages >= page) { initialIndex = rowsPerPage * page; } else { page = 0; } var eventingSummary = "

" + ""; for (var i = initialIndex; i < eventingHistory.length && i < (rowsPerPage * (page + 1)); i++) { eventingSummary += ""; } eventingSummary += "
" + "TimestampRetryServerRetryEventTypeURL" + "
" + eventingHistory[i].timestamp + "" + eventingHistory[i].retryCount + "" + eventingHistory[i].serverRetryCount + "" + eventingHistory[i].eventType + "" + eventingHistory[i].URL.replace(/\?.*$/ig, "") + "
"; if (formatted) { display_WebSDKAlert(eventingSummary); } else { eventingSummary = eventingSummary.replace(/<\/td>]+>/ig, " | "); eventingSummary = eventingSummary.replace(/<\/td>/ig, " | "); eventingSummary = eventingSummary.replace(/<\/td><\/tr>/ig, "
"); eventingSummary = eventingSummary.replace(/
/ig, "\n"); eventingSummary = eventingSummary.replace(/<[^>]+>/ig, ""); alert(eventingSummary); } } function setupHeartbeatTimeoutCheck(enabled, timeout) { heartbeatTimeoutEnabled = enabled; heartbeatTimeout = timeout; log.debug('Heartbeat timeout enabled: ' + enabled + ' timeout: ' + timeout + 'sec(s)'); } /** * Function for verifying if the heartbeat is on time */ function isHeartbeatOntime() { if (!window.frames[EventingID]) { log.error("Heartbeat timed out: no pushlet"); return false; } heartbeatTimestamp = window.frames[EventingID].lastHeartbeat; var now = new Date(); if (heartbeatTimestamp == null) { // not received heartbeat yet heartbeatTimestamp = now; window.frames[EventingID].lastHeartbeat = heartbeatTimestamp; log.debug('HeartBeat check, not received yet, setting HeartBeat = Now = ' + heartbeatTimestamp); } var heartbeatDiff = (now - heartbeatTimestamp) / 1000; if (heartbeatTimeoutEnabled && (heartbeatDiff >= heartbeatTimeout)) { log.error('Heartbeat timed out, now: ' + now + ' - lastHeartBeat: ' + heartbeatTimestamp + ' - difference: ' + heartbeatDiff + ' sec(s)'); return false; } else { return true; } } /** * Function for verifying if eventing is active on the server side, in order to prevent false failure notification */ function isEventingActive() { log.info("isEventingActive() ? " + eventingActive); try { if (eventingActive) { log.info("Eventing is active, requestig activity state to the server."); var params = "checkEventingActivity=true&uid=" + evt_uid + "&"; var xmlhttp = createAJAXRequest(); xmlhttp.open("POST", getFullURL(EventingURL), true); xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8"); xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState == 4) { var result = xmlhttp.responseText; if (xmlhttp.status != 200 || result != "true") { eventingActive = false; } log.debug("Eventing activity request http status: " + xmlhttp.status + " result: '" + result + "'"); } }; xmlhttp.send(params); window.setTimeout(function() { if (xmlhttp.readyState != 4) { try { log.debug("Aborting request"); xmlhttp.abort(); } catch (e) { log.error("Unable to abort: ", e); } // log.info("Check eventing activity state timed out, marking as inactive"); eventingActive = false; } else { var result = xmlhttp.responseText; if (result != "true") { log.debug("Eventing not active: " + result); eventingActive = false; } } }, 5000); } return eventingActive; } catch (e) { log.error("Unable to check eventing activity: ", e); log.debug("Returning result as inactive"); } return false; } // function sets flag to indicate unload should NOT trigger logoff action function ignoreUnloadForLogoff() { document.ignoreLogoff = true; if (window.checkWindowsID) { window.clearInterval(checkWindowsID); } } // function is invoked when outer display is unloaded // - triggers logoff upon if window is last TOP window // - send synchronous action to end the users session function displayUnLoad() { window.closing = true; unloadAllDisplays(); if (document.ignoreLogoff !== true && logoffCalled !== true) { var win = findFirstRemainingOpenWindow(window); if (win == null && window.closing) { log.info("Last remaining top window, invoking logoff"); logoff(); } } } /** * Function used to verify if the eventing frame is disconnected */ function isEventingFrameDisconnected() { return (window.frames[EventingID] && window.frames[EventingID].document.readyState === 'complete'); } /** * Function used to verify if failover is being attempted */ function isAttemptingFailover() { // (recyclePushlet == false), if pushlet is recycling it's not attempting failover return ((isEventingConnected === false || isEventingFrameDisconnected()) && failoverInitialized === true && recyclePushlet === false); } /** * Function used to verify if WSDK is configured for handling the failover on the clientside */ function isClientSideFailover() { return (failoverServerList != null); } function getServerURL() { var serverURL = ""; if (serverProtocol != "" && serverAddress != "" && serverPort != "" && applicationContext != "") { serverURL = serverProtocol + "://" + serverName + ":" + serverPort + "/" + applicationContext + "/"; } return serverURL; } function setServer(protocol, newAddress, serverNm, port, context, footerServerAndPort, dojoUrl) { var oldServer = serverName; connectEventing(); disconnectMessageSent = false; serverName = serverNm; serverProtocol = protocol; serverPort = port; context = context.replace(new RegExp("^/"), ""); applicationContext = context.replace(new RegExp("/$"), ""); eventingCurrentRetry = 0; window.top.topWindow.frames[EventingID].frameElement.style.visibility = 'visible'; updateRequireJSModuleLocations("//" + serverName + ":" + serverPort, dojoUrl, oldServer, serverName); if (serverAddress !== "" && serverAddress !== newAddress) { // The server name has changed, execute fail over actions if (window.top.topWindow.frames[EventingID] != null) { var msg = getNLS('failover.connected.start') + serverName + getNLS('failover.connected.end.refresh'); addMessage(msg, MSG_TYPE_Message, 'eventingConnect', MSG_STD_TIMEOUT, true); window.top.topWindow.frames[EventingID].refreshAllWindows(failoverRefreshReason); } // For ODV we don't show that the display is being refreshed var msg = getNLS('failover.connected.start') + serverName + getNLS('failover.connected.end'); sendODVMessage(msg); handleJBossFailoverEvent(newAddress, serverAddress); } else { if (serverAddress !== "") { if (recyclePushlet) { var msg = getNLS('recycle.connected.start') + serverName + getNLS('recycle.connected.end'); log.info(msg); } else if (failoverInitialized) { var msg = getNLS('failover.connected.start') + serverName + getNLS('failover.connected.end'); addMessage(msg, MSG_TYPE_Message, 'eventingConnect', MSG_STD_TIMEOUT, true); sendODVMessage(msg); } } } deleteMessageById('connectionFailure', true); serverAddress = newAddress; showEventingDiv(); failoverInitialized = true; // mark pushlet as not being recycled recyclePushlet = false; ignoreHeartbeat = true; // Heartbeat timeout will be enabled after when the first event is received eventingActive = true; // Eventing is active addEventingHistoryEntry(new Date(), "-", "-", "PushletConnected", serverProtocol + "://" + serverName + ":" + serverPort + "/" + applicationContext + "/"); log.info("Initializing Pushlet - setServer: " + serverProtocol + "://" + serverName + ":" + serverPort + "/" + applicationContext + "/"); } function updateRequireJSModuleLocations(serverPath, dojoUrl, oldServer, newServer) { if (oldServer == null || oldServer === '') { return; } for ( var key in require.packs) { var pack = require.packs[key]; var location = require.packs[key].location; if (typeof location === "string") { if (location.search(/^http[s]?\:\/\//) === 0) { // absolute paths updateAbsoluteRequirePath(pack, oldServer, newServer, location); } else if (location.indexOf("//") === 0) { // expected for everything after a previous failover updateProtocolRelativeRequirePath(pack, oldServer, newServer, location); } else if (location.indexOf("/") === 0) { // Siemens custom modules updateRootRequirePath(pack, serverPath, location); } else { // dojo initial module paths (relative) updateRelativeRequirePath(pack, serverPath + dojoUrl + key); } } } } function updateRelativeRequirePath(pack, dojoUrl) { pack.location = dojoUrl; } function updateProtocolRelativeRequirePath(pack, oldServer, newServer, location) { pack.location = location.replace("//" + oldServer + ":", "//" + newServer + ":"); } function updateRootRequirePath(pack, serverPath, location) { pack.location = serverPath + location; } function updateAbsoluteRequirePath(pack, oldServer, newServer, location) { location = location.replace(/^http[s]?\:\/\//, '//'); updateProtocolRelativeRequirePath(pack, oldServer, newServer, location); } /** * Function responsible for notifying the backend that a failover has happened, application eventualy need to be * notified of a jboss failover in order to recover things that can't be recovered through display refresh (e.g. * Standalone OLM) */ function handleJBossFailoverEvent(newServer, oldServer) { window.parent.display_sendAction('HANDLE_JBOSS_FAILOVER', '', 'newServer=' + newServer + "&oldServer=" + oldServer); } function setFailoverServerList(retries, list) { failoverServerIndex = 0; failoverCurrentServerRetry = -1; failoverServerRetries = retries; failoverServerList = list; } function hideEventingDiv() { var evImg = document.getElementById('eventingIcon'); if (evImg != null) { evImg.style.visibility = 'hidden'; } var evText = document.getElementById('eventingText'); if (evText != null) { evText.style.visibility = 'hidden'; } } function hideEventingIFrame() { var evIF = document.getElementById(EventingID); if (evIF != null) { evIF.style.visibility = 'hidden'; } var evText = document.getElementById('eventingText'); if (evText != null) { evText.style.visibility = 'hidden'; } } function showEventingDiv() { var evImg = document.getElementById('eventingIcon'); if (evImg != null) { evImg.style.visibility = 'visible'; } var evText = document.getElementById('eventingText'); if (evText != null) { evText.style.visibility = 'visible'; } } function connectEventing(isJboss) { if (isJboss == undefined || isJboss) { isEventingConnected = true; } var evIcon = document.getElementById('eventingIcon'); if (evIcon != null) { evIcon.classList.remove('WFConnectingIcon', 'WFNoConnectionIcon'); evIcon.classList.add('WFConnectedIcon'); } var evText = document.getElementById('eventingText'); if (evText != null) { evText.innerHTML = getNLS('connectivity.connected'); } } function disconnectEventing(isJboss) { if (isJboss == undefined || isJboss) { isEventingConnected = false; } var evIcon = document.getElementById('eventingIcon'); if (evIcon != null) { evIcon.classList.remove('WFConnectedIcon'); evIcon.classList.add('WFNoConnectionIcon'); } var evText = document.getElementById('eventingText'); if (evText != null) { evText.style.visibility = ""; evText.innerHTML = getNLS('connectivity.disconnected'); } } function setWindowAsTopWindow(inOpenWindowList) { var isNewTopWin = (window != top.topWindow); // if window is same as the current top window then stop processing.... if (!isNewTopWin) { return; } // if current top window exists make sure you clear the name of the top window clearWindowName(top.topWindow); if (inOpenWindowList == null) { inOpenWindowList = []; } // Creating new window list array openWindowList = []; openWindowList[0] = window; if (inOpenWindowList != null) { // Update window list array with input list contents var nCounter = 1; for (var inCounter = 0; inCounter < inOpenWindowList.length; inCounter++) { if (inOpenWindowList[inCounter] == null || inOpenWindowList[inCounter] == window) { continue; } openWindowList[nCounter] = inOpenWindowList[inCounter]; // the window has moved into slot nCounter, so update the number at the end of the title setWindowTitle(nCounter); nCounter++; } } // if Singleton logger and initial setting of topWindow mark window as window 0 if (window.LOGGER_SINGLETON && (window.winName == null || window.winName == logger.LOG_ALL_WINDOWS)) { log.updateWindowName("0"); } // If setting top window is NOT initial callup and Logger Singleton is specified // then recreate logger instance and update all references of logger in the // other windows opened if (window.LOGGER_SINGLETON) { // create new CLONED instance of logger // when new top window occurs. Browser / JS doesn't let you access // object instance created in another window after that window is closed try { var newLogger = new LOGGER(); newLogger.COPY_LOGGER(logger); logger = newLogger; log.updateLogger(logger); } catch (ex) { alert("exception creating logger : " + ex.toString()); } // for all other opened windows, update reference to logger and log data for (var i = 0; i < openWindowList.length; i++) { var inWin = openWindowList[i]; // only update window if window is open and not the NEW top window if (inWin != null && inWin != window && !inWin.closed) { // update the log reference for all open windows... if (inWin.updateLogger != null) { openWindowList[i].updateLogger(logger); } } } } strayDeltas = {}; // Set this window as top window top.topWindow = window; // Set the name of the top window so it can be found later by a child window if the window references somehow are // lost applyTopWindowName(window); thisIsTheTopWindow = true; log.debug('topWindow updated'); // the window has moved into slot 0, so update the number at the end of the title setWindowTitle(0); // add handler for the unload event, this function is on sdk.js window.addEventListener("unload", handleTopWindowShutDown, false); // reset variable for topWindow for existing windows for (var i = 1; i < openWindowList.length; i++) { try { if (openWindowList[i] != null && (openWindowList[i].document)) { openWindowList[i].topWindow = topWindow; openWindowList[i].hideEventingDiv(); } } catch (e) { log.error('Failure at SetWindowAsTopWindow: ', e); } } if (window.pushletEnabled == true) { require([ 'dojo/domReady!' ], function() { // Note: we could load the pushlet on domReady!, but then document.readyState // will not reach 'complete' until if and when the pushlet connection is ended. initEventing(); showEventingDiv(); }); } } function clearWindowName(win) { if (win != null) { win.name = ""; } } function applyTopWindowName(win) { win.name = getTopWindowName(); log.trace("setting top window to: " + window.name); } function transferOpenWindowList(inOpenWindowList) { // Creating new window list array openWindowsRef = []; if (inOpenWindowList != null) { // Update window list array with input list contents var nCounter = 0; for (var inCounter = 0; inCounter < inOpenWindowList.length; inCounter++) { if (inOpenWindowList[inCounter] == null) { continue; } openWindowsRef[nCounter] = inOpenWindowList[inCounter]; nCounter++; } } } function transferTopWindowInformation(inCurrentEventSeqId, inFailoverServerList, inServerProtocol, inServerAddress, inServerName, inServerPort, inApplicationContext, inStrayDeltas) { // Update sequence id currentEventSeqId = inCurrentEventSeqId; // Set previous server variables to force pushlet to be reconnected to the same server it was connected to if (inFailoverServerList != null && inServerProtocol != "" && inServerAddress != "" && inServerPort != "" && inApplicationContext != "") { failoverServerList = inFailoverServerList; serverProtocol = inServerProtocol; serverAddress = inServerAddress; serverName = inServerName; serverPort = inServerPort; applicationContext = inApplicationContext; if (inStrayDeltas) { strayDeltas = {}; for ( var key in inStrayDeltas) { var deltas = inStrayDeltas[key]; if (deltas && deltas.length > 0) { // efficiently copy the array to the new window strayDeltas[key] = Array.prototype.slice.call(deltas, 0); log.trace('Transfered ' + deltas.length + ' "stray" deltas to the new topWindow'); } } } log.debug("Saving top window server: " + serverProtocol + "://" + serverName + "[" + serverAddress + "]:" + serverPort + "/" + applicationContext); } } var EventingID = "eventing"; var EventingURL = "receiveEvents.do"; var EventingInterval = 5000; var eventingRunning = false; var evt_uid = ""; function getEventingURL() { var url = EventingURL + '?currentEventSeqId=' + currentEventSeqId + '&uid=' + evt_uid + '&eventingReconnection=true¤tServerAddr=' + serverAddress; if (top.window.logonPage == true) { url += "&logonPage=true"; } return url; } function createPushletFrame(event) { if (window.top.topWindow.frames[EventingID] != null) { return true; } if (top.document == null || top.document.body == null) { return false; } var ifr = window.top.document.createElement('IFRAME'); ifr.id = EventingID; ifr.name = EventingID; var url = getEventingURL(); ifr.src = url; ifr.className = 'WFFooterIframe'; try { top.document.body.appendChild(ifr); } catch (e) { log.error("error adding element ex: " + e); return false; } // NOTE: load event is not fired until pushlet is FINISHED processing content ifr.addEventListener("load", reloadFrameFunction, true); return true; } // create and start new eventing process in new eventing window function initEventing() { try { // Don't make duplicate frames if (window.top.topWindow != null && window.top.topWindow.frames[EventingID] != null) { // addMessage('Eventing Running', MSG_TYPE_Message); return; } // check window state if (document.readyState !== 'complete') { var loadInitEventing = function() { document.onreadystatechange = null; initEventing(); if (window.removeEventListener) window.removeEventListener('load', initEventing, false); }; // not ready, wait document.onreadystatechange = loadInitEventing; // fallback to onload if (window.addEventListener) { window.addEventListener('load', loadInitEventing, false); } return; } // check window state reloadFrameFunction = function(event) { top.window.initPushletTimeoutId = setTimeout( "hideEventingIFrame();" + "log.info('restarting pushlet from setTimeout...'); " + "if( !stopRetry )" + "{" + " if(eventingCurrentRetry < eventingMaxRetry)" + " {" + " disconnectEventing();" + " var msg = getNLS('failover.disconnect.start') + serverName + getNLS('failover.disconnect.end');" + // NOTE: on firefox reload function is what triggers pushlet recycle, not monitoring frame // when recycling do not show error message on first retry " if (!(recyclePushlet && eventingCurrentRetry == 0)) { " + " addMessage(msg, MSG_TYPE_ERROR, 'connectionFailure', 0, true);" + " addMessage(getNLS('failover.attempt') + (++eventingCurrentRetry) + '. . .', MSG_TYPE_WARNING, 'failoverAttempt', MSG_STD_TIMEOUT, true);" + " }" + " if(!disconnectMessageSent) {" + " disconnectMessageSent = true;" + " sendODVMessage(msg);" + " }" + " recycleEventing();" + " } else {" + " sendODVMessage(getNLS('failover.reconnection.failure.odv'), true);" + " parent.applicationSessionHandler(true);" + " }" + "}", 3000); }; eventingRunning = createPushletFrame(); } catch (e) { addMessage('Failed to initialize eventing frame: ', e); } // start process to monitor eventing process if (eventingRunning) { log.debug('eventing frame initialized'); monitorEventing(); } } function getFailoverServer() { var failoverServer = null; if (failoverServerList != null && failoverServerList.length > 0) { if (failoverCurrentServerRetry < (failoverServerRetries - 1)) { failoverCurrentServerRetry++; } else { failoverCurrentServerRetry = 0; failoverServerIndex++; if (failoverServerIndex > failoverServerList.length) { failoverServerIndex = 0; } } if (failoverServerIndex == 0) { failoverServer = getServerURL(); } else { failoverServer = failoverServerList[failoverServerIndex - 1] + "/" + applicationContext + "/"; } } log.info("Getting failover server: " + failoverServer + " retries: " + failoverCurrentServerRetry); return failoverServer; } // restart new eventing process in existing eventing window function recycleEventing() { // get reference to eventing iframe var eventingFrameRef = window.frames[EventingID]; try { var failoverUrl = getEventingURL(); var failoverServer = getFailoverServer(); if (failoverServer != null) { failoverUrl = failoverServer + failoverUrl; } // recycle may be caught by timeout or monitor code.. // prevent timeout code from executing if it hasn't been triggered yet // which will prevent recycle from happening twice if (top.window.initPushletTimeoutId && top.window.initPushletTimeoutId > 0) { window.clearTimeout(top.window.initPushletTimeoutId); top.window.initPushletTimeoutId = -1; } var recycleReason = ((recyclePushlet && eventingCurrentRetry <= 1) ? "PushletRecycle" : "PushletReconnectionTry"); addEventingHistoryEntry(new Date(), eventingCurrentRetry, failoverCurrentServerRetry, recycleReason, failoverUrl); // // Debug messages // addMessage('Cookie : ' + document.cookie); // addMessage('URL : ' + failoverUrl); eventingFrameRef.location = failoverUrl; } catch (e) { log.error("Unable to restart eventing: ", e); addMessage('Unable to restart eventing.', MSG_TYPE_ERROR); } } // forces a failover to occur. This function is only used for debugging function forceFailover() { if (failoverServerList != null && failoverServerList.length > 0) { failoverServerIndex++; if (failoverServerIndex > failoverServerList.length) { failoverServerIndex = 0; } recycleEventing(); } else { refreshAllWindows(failoverRefreshReason); } } // monitorEventing is an iterative process that montitors the eventing process // and restarts it if it dies var monitorEventingTimer; function monitorEventing() { try { var eventingIFrame = window.top.topWindow.frames[EventingID]; if (eventingIFrame) { var restartPushlet = false; try { if (eventingIFrame.document.readyState == 'complete') { eventingIFrame.frameElement.style.visibility = 'hidden'; restartPushlet = true; hideEventingIFrame(); // if recycling the pushlet failed to re-establish then // start failover... if (recyclePushlet && eventingCurrentRetry > 0) { recyclePushlet = false; failoverInitialized = true; log.error('Eventing retry > 0, pushlet recycle failure. Initializing failover !'); } } else if (heartbeatTimeoutEnabled && isEventingConnected) { var reloadPushlet = false; // Pushlet will set pageState variable on loading of frame // - first JS in head will set state to INIT // - last JS cmd in body will set state to LOADED var pageState = eventingIFrame.pageState; if (pageState != null) { var heartBeatOK = isHeartbeatOntime(); if (!heartBeatOK) { // if Pushlet has just started loading content then give approprirate time to transition // from INIT to LOADED if (pageState == "INIT") { if (eventingIFrame.loadingTS == null) { log.info("Setting timestamp to allow page to transition from INIT to LOADED"); eventingIFrame.loadingTS = new Date(); } else { var threshold = 30000; // threshold > monitor interval var delta = (new Date()).getTime() - eventingIFrame.loadingTS.getTime(); if (delta > threshold) { log .error("Reloading pushlet due to pageState did not transition from INIT to LOADED in time(ms): " + threshold); reloadPushlet = true; eventingIFrame.loadingTS = null; } } } // if page has loaded ALL of the initial content else if (pageState = "LOADED") { log.error("Eventing frame is loaded but heartbeat is behind, reload pushlet"); reloadPushlet = true; } log.info("heartbeat is behind..check if eventing is active"); var eventActive = isEventingActive(); if (eventActive) { // NOTE this case was hit on CAISO // Server had pushlet connection and able to // write events // Client had pushlet but was not processing // events log.error("Server reporting eventing as active but heartbeat is behind!!"); } } // TODO: ?? should we also check when (heartbeat == OK) that isEventingActive() returns true // In my opinion this would detect that the JBoss server is responsive // or not for NEW requests.. It doesn't mean the current pushlet is bad if it fails } // if JS pageState at head of page has not loaded then check if frame is in process of loading else { // check if eventing frame is being loaded but has // NOT yet loaded JS for Eventing Frame's pageState variable var readyState = eventingIFrame.document.readyState; if (readyState == "interactive" || readyState == "loading ") { // put TS to determine if frame loads JS from // pushlet in some threshold // if not mark page as dead if (eventingIFrame.initLoadingTS == null) { eventingIFrame.initLoadingTS = new Date(); } else { var threshold = 30000; // threshold > // monitor interval var delta = (new Date()).getTime() - eventingIFrame.initLoadingTS.getTime(); if (delta > threshold) { log.error("Reloading pushlet due to pageState NOT set for pushlet in time(ms): " + threshold); reloadPushlet = true; eventingIFrame.initLoadingTS = null; } } } } if (reloadPushlet) { log.info("Marking pushlet to be reloaded"); restartPushlet = true; recyclePushlet = true; hideEventingIFrame(); } } } catch (e) { restartPushlet = true; hideEventingIFrame(); } // if pushlet is trying to be restarted due to recycle event then // display appropriate messages // and reconnect the pushlet if (restartPushlet && recyclePushlet && eventingCurrentRetry == 0) { eventingCurrentRetry++; disconnectEventing(); var msg = getNLS('recycle.disconnect.start') + serverName + getNLS('recycle.disconnect.end'); log.info("restarting pushlet from monitor for first attempt..."); log.info(msg); recycleEventing(); } else if (restartPushlet && failoverInitialized && !stopRetry) { updateConnectivityStatus(connections); if (eventingCurrentRetry < eventingMaxRetry) { disconnectEventing(); var msg = getNLS('failover.disconnect.start') + serverName + getNLS('failover.disconnect.end'); // Do not show for the first attempt to reconnect if (eventingCurrentRetry > 1) { addMessage(msg, MSG_TYPE_ERROR, 'connectionFailure', 0, true); addMessage(getNLS('failover.attempt') + (++eventingCurrentRetry) + '. . .', MSG_TYPE_WARNING, 'failoverAttempt', MSG_STD_TIMEOUT, true); } else { ++eventingCurrentRetry; } if (!disconnectMessageSent) { disconnectMessageSent = true; sendODVMessage(msg); } recycleEventing(); } else { addEventingHistoryEntry(new Date(), eventingCurrentRetry, "-", "MaxRetryReached", "-"); sendODVMessage(getNLS('failover.reconnection.failure.odv'), true); closeWindowsOnSessionChange(true); return; } } } } catch (e) { log.error('Failure at monitorEventing: ', e); } // if monitorEventing not running, start the process try { if (!(monitorEventingTimer)) { monitorEventingTimer = setInterval(monitorEventing, EventingInterval); } } catch (e) { log.error('Failure at monitorEveting - setTimer: ', e); } } function sendODVMessage(message, closeWindow) { if (closeWindow == null) { closeWindow = false; } try { // passMsg only exists under ODVWebUI application if (window.passMsg) { passMsg(message, closeWindow); } } catch (e) { } } function checkWindowReferencesInterval() { try { // if popup window cancel timer, NOTE it is possible interval started first time // before property was set by calling window...hence the second check if (window.top.isUnmanagedPopup) { clearInterval(checkWindowsID); return; } var openWindowList = []; // if top window.. check for any window references that have gone away if (thisIsTheTopWindow) { if (topWindow == null) { log.error("isTopWindow but topWindow is null"); window.topWindow = window; } openWindowList = topWindow.openWindowList; } else { log.trace("NON topWindow"); try { if (!topWindow) { // if no top window..but opener knows about its top window then re-assign var windowOpener = getWindowOpener(window); if (windowOpener.isOpener && !windowOpener.window.closed && windowOpener.window.top.topWindow) { log.debug("assigned topWindow from opener"); topWindow = windowOpener.window.top.topWindow; } // check to see if one of the registered windows in window list can be used to get topWindow else { var openWindowsRef = window.openWindowsRef; if (openWindowsRef != null) { for (var i = 0; i < openWindowsRef.length; i++) { var win = openWindowsRef[i]; if (win != null && !win.closed && win.topWindow != null) { log.info("assigned topWindow from another registered window"); topWindow = win.topWindow; break; } } } if (topWindow == null) { // NOTE: if we are hitting this case ( fall back code) we may need to force this list to be // up to date // by either copying it each poll cycle (when top window is found) or whenever windows are // added / closed log.debug("unable to find TopWindow from local copy of open window list"); } } } } catch (e) { log.error("caught exception accessing opener.top to find top window"); } // now if top window still isn't set then try to lookup top window and force window to be // registered with the top window if (topWindow == null) { topWindow = findTopWindowByName(); if (topWindow != null && !topWindow.closed && topWindow != window.top) { topWindow.registerWindow(window); } } // if STILL NO top window defined...How did reference get lost?? if (topWindow == null) { checkWindowFailCnt++; // add error message after N failures if (checkWindowFailCnt >= checkWindowErrorMsgAfterCnt) { var msg = getNLS('window.topwindow.reference.disconnected'); addMessage(msg, MSG_TYPE_ERROR, msg); } if (checkWindowFailCnt >= maxCheckWindowFails) { log.error("No top window defined for child window..closing dead window!!!"); if (top.showErrorDisplay) { top.showErrorDisplay('window.disconnected', 'window.disconnected.unloaded', window.top); } else { // close window; top.window.close(); } clearInterval(checkWindowsID); } else { log.info("No top window defined for child window count:" + checkWindowFailCnt + " !!..try again next interval"); } return; } else { if (checkWindowFailCnt > 0) { log.info("window reconnected to top window"); deleteMessageById("window.disconnected"); checkWindowFailCnt = 0; } } try { log.trace("getting OpenWindow list from topWindow"); openWindowList = topWindow.openWindowList; } catch (e) { log.debug("Exception getting OpenWindow list from topWindow and using local copy"); var openWindowsRef = window.openWindowsRef; if (openWindowsRef != null) { for (var i = 0; i < window.openWindowsRef.length; i++) { if (openWindowsRef[i] && openWindowsRef[i] != null && !openWindowsRef[i].closed) { if (openWindowsRef[i] == window) { try { log.info("setting NEW top window..."); window.setWindowAsTopWindow(openWindowsRef); } catch (e) { log.error('Error setting new top window.', e); } break; } } } log.debug("assigning window list from ref copy"); openWindowList = openWindowsRef; } } } log.trace("check if window registered"); // make sure the window is registered var found = false; if (openWindowList == null) { log.error("window not registered and topWindow not found"); } else { for (var i = 0; i < openWindowList.length; i++) { if (openWindowList[i] != null && openWindowList[i] == window) { found = true; break; } } } log.trace("window found: " + found); // if server is not found then try to re-register window... probably should // refresh the display too if (!found) { if (topWindow == null) { log.error("window not registered and topWindow not found"); } else { log.info("re-registring display and refreshing content"); topWindow.addWindowToOpenWindowList(window); reloadContentDisplay(); } } initializeDelayedDeltas(); } catch (e) { log.error("Error processing exception: ", e); } } function findTopWindowByName() { var topWin = null; var name = getTopWindowName(); if (name != "") { var closeWindow = true; try { log.trace("trying to find top window by name: " + name); topWin = window.open('javascript:', name); // first check if document is accessible (document.domain should match) topWin.document; var URL = topWin.location.href; var isCorrectURL = URL.indexOf('.do') > -1; log.info("URL of top Window is: " + URL); if (!isCorrectURL) { closeWindow = true; } else { closeWindow = false; } } catch (e) { log.error("failed to open top window"); } if (closeWindow && topWin != null) { try { topWin.close(); } catch (e) { log.error('failed to close window: ' + name); } topWin = null; } } return topWin; } function getTopWindowName() { var windowName = ""; var uid = null; if (parent.uid != null) { uid = parent.uid; } if (uid != null) { windowName = "TOPWINDOW_" + uid; } return windowName; } function restoreTopWindow(activeSession) { log.info('Restoring top window.'); var topWin = findTopWindowByName(); if (topWin != null) { topWin.focus(); log.info('Top window ' + topWin.name + ' restored.'); closeSelfNoPrompt(); } else { // if eventing is active, then this means we opened an empty window but there's still another window active, // with an active session if (activeSession) { log.warning('The session is active but the top window could not be restored.'); } else { log.error('Top window could not be found.'); } document.getElementById('duplicateLogonContent').style.display = ''; document.getElementById('restoreWindowContent').style.display = 'none'; } } // Used by logger window to simulate a window reference being lost function removeWindowFromList() { var openWindowList = top.topWindow.openWindowList; for (var i = 0; i < top.topWindow.openWindowList.length; i++) { if (openWindowList[i] != null && openWindowList[i] == window) { openWindowList[i] = null; break; } } } function reloadContentDisplay() { log.info("reloading content frame"); var contentFrame = getContentFrame(); if (contentFrame != null && contentFrame.document != null) { var contentDoc = contentFrame.document; var pageId = contentDoc.getElementById(PAGE_ID_FIELD_NAME); if (pageId != null && pageId.value != "" && contentFrame.nondeltaDisplayUpdate) { contentFrame.nondeltaDisplayUpdate(contentFrame, pageId.value); } else { addMessage("Unable to reload content frame upon reconnecting display"); } } } /* * Methods are only for testing purposes.... */ function removeFromParent() { addMessage("test removeFromParent"); if (!thisIsTheTopWindow) { if (topWindow != null) { var openWindowList = topWindow.openWindowList; for (var i = 1; i < openWindowList.length; i++) { if (openWindowList[i] != null && openWindowList[i] == window) { openWindowList[i] = null; } } } topWindow = null; } } function checkChildWindows() { addMessage("test checkChildWindows"); if (!thisIsTheTopWindow || topWindow == null) { return; } var openWindowList = topWindow.openWindowList; for (var i = 1; i < openWindowList.length; i++) { if (openWindowList[i] != null && !(openWindowList[i].closed)) { openWindowList[i].addMessage("child window!!"); } } } /** * Function used to update the menu content on all windows through a delta replacement and reload the content frame */ function reloadDisplayOnAllWindows() { log.info("replacing displays"); if (openWindowList != null) { // loop thru all open windows for (var i = 0; i < openWindowList.length; i++) { try { log.info("calling reload content display"); openWindowList[i].refreshCurrentPage(); } catch (e) { log.error('Failed to reload content display: ', e); } } } else { try { log.info("reloading content, windowlist is null"); refreshCurrentPage(); } catch (e) { log.error('Failed to reload content display: ', e); } } } function updateConnectivityInfo(server, newConnections) { updateServerInfo(server); if (window.ODV && window.ODV.isDashboard && window.ODV.isDashboard()) { window.ODV.updateConnectionStatus(newConnections); } else { updateConnectivityStatus(newConnections); } } /** * Update the jboss connection info shown in the info box * */ function updateServerInfo(server) { var infoBox = document.getElementById('debugInfo'); if (infoBox) { var visibility = infoBox.style.visibility; if (!visibility || visibility == 'visible') { document.getElementById("serverProp").innerHTML = server; } } } /** * Update the connection status list with the new info from the pushlet (ConnectivityMonitor) */ function updateConnectivityStatus(newConnections) { defineConnectionStatus(newConnections); // if there are any changes on the connections, perform the determined actions if (connectionStatusChange) { if (hasDisconnections == true) { disconnectEventing(false); } else { connectEventing(false); } var windowList = getOpenWindows(); if (windowList != null) { var popup = windowList[0].document.getElementById('conMonitor'); if (popup.style.visibility == '' || disconnectionWarning) windowList[0].display_openConnectionMonitor(false); // go through all windows and hide/display the disconnection watermark for (var i = 0; i < windowList.length; i++) { var contentFrame = windowList[i].getContentDom(); var visibility = (disconnectionWarning == true) ? '' : 'none'; var waterMark = contentFrame.getElementById('disconWaterMark'); if (waterMark) { waterMark.style.display = visibility; } var waterMarkImg = contentFrame.getElementById('disconWaterMarkImg'); if (waterMarkImg) { waterMarkImg.style.display = visibility; } } } } } /** * Updates the connection list with the new info provided by the connectivity monitor task and determine if an action * should occur (e.g. bring up the connection monitor, show disconnection watermark, etc.) */ function defineConnectionStatus(newConnections) { var newConLength = newConnections.length, conLength = connections.length; connectionStatusChange = false; hasDisconnections = false; // check if the jboss connection is down and react accordingly if (!isEventingConnected) { updateJbossConnectionDetails(); return; } // go through the new connection list and determine what has changed for (var i = 0; i < newConLength; i++) { var newConInfo = newConnections[i], foundEqual = false; for (var j = 0; j < conLength; j++) { var conInfo = connections[j]; if (newConInfo.name === conInfo.name && newConInfo.type === conInfo.type) { foundEqual = true; // if the state of a connection has changed, mark for update if (newConInfo.status !== conInfo.status) { connectionStatusChange = true; // if the new status is disconnected, mark to show the popup and display disconnection warning if (newConInfo.status === 'disconnected') { disconnectionWarning = true; hasDisconnections = disconnectionWarning; } } break; } if (newConInfo.status === 'disconnected') { hasDisconnections = true; } } // in case the connection is new, mark it for update and check if it requires a disconnection warning if (!foundEqual) { connectionStatusChange = true; if (newConInfo.status === 'disconnected') { disconnectionWarning = true; } } } if (!hasDisconnections) { disconnectionWarning = hasDisconnections; } if (disconnectionWarning) { top.openWindowList[0].document.getElementById('acknowledgeButton').disabled = false; } connections = newConnections; } /** * When the jboss server goes down, update the jboss connections to disconnected on the monitor popup */ function updateJbossConnectionDetails() { // go through the connection array and change the status of jboss connections connectionStatusChange = false; for (var i = 0; i < connections.length; i++) { var conInfo = connections[i]; if (conInfo.name == getNLS('connectivity.name.server') && conInfo.status === 'connected') { connectionStatusChange = true; disconnectionWarning = true; conInfo.status = 'disconnected'; } } hasDisconnections = true; } /** * This functions makes the disconnection watermark to all windows. */ function acknowledgeDisconnection() { // resets the disconnection warning that triggers the watermark top.disconnectionWarning = false; // go through all windows and hide the disconnection watermark var windowList = top.openWindowList; if (windowList != null) { windowList[0].document.getElementById('acknowledgeButton').disabled = 'disabled'; for (var i = 0; i < windowList.length; i++) { var contentFrame = windowList[i].getContentDom(); var waterMark = contentFrame.getElementById('disconWaterMark'); if (waterMark) { waterMark.style.display = 'none'; } var waterMarkImg = contentFrame.getElementById('disconWaterMarkImg'); if (waterMarkImg) { waterMarkImg.style.display = 'none'; } } } } function setTopWindow() { // if no top window was defined but opener knows about its top window then re-assign var windowOpener = getWindowOpener(window); if (windowOpener.isOpener && !windowOpener.window.closed && windowOpener.window.top.topWindow) { log.debug("Setting top window"); window.top.topWindow = windowOpener.window.top.topWindow; } } /* start block _extraContent_ */ /* end block */