'use strict'; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /** * Licensed Materials - Property of IBM * IBM Business Analytics (C) Copyright IBM Corp. 2019, 2020 * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */ /** * @class RenderSequenceImpl * @hideconstructor * @classdesc */ define(['underscore', '../../../../lib/@waca/dashboard-common/dist/api/impl/CallbackInvoker', '../../../../lib/@waca/dashboard-common/dist/core/APIFactory', '../../../../lib/@waca/dashboard-common/dist/api/Error', '../api/RenderContextAPI', '../s12y/RenderSequenceInfo', '../s12y/ServiceabilityRenderingInfo', '../s12y/ServiceabilitySQLInfo', './RenderContextImpl', '../s12y/RenderingInfo'], function (_, CallbackInvoker, APIFactory, APIError, RenderContextAPI, RenderSequenceInfo, ServiceabilityRenderingInfo, ServiceabilitySQLInfo, RenderContextImpl, RenderingInfo) { var _class, _temp; var RenderSequenceImpl = (_temp = _class = function (_CallbackInvoker) { _inherits(RenderSequenceImpl, _CallbackInvoker); /** * TODO: remove the usage of dashboardAPI.getService when dashboardAPI.getFeature includes the glass service * @param {Object} options * @param {DashboardAPI} options.dashboardAPI * @param {Object[]} options.features */ function RenderSequenceImpl(_ref) { var dashboardAPI = _ref.dashboardAPI, features = _ref.features, content = _ref.content; _classCallCheck(this, RenderSequenceImpl); var logger = dashboardAPI.getService(dashboardAPI.GLOBAL_SERVICES.LOGGER); var _this = _possibleConstructorReturn(this, _CallbackInvoker.call(this, { logger: logger })); _this._logger = logger; _this._s12yAPI = features['Serviceability']; _this._renderStepProviders = []; _this._currentRenderContext = {}; _this.content = content; var impl = _this; _this.onStartTaskExecution(function (options) { impl.s12yOnStartTaskExecution(options); }); _this.onResolveTaskExecution(function (options) { impl.s12yOnResolveTaskExecution(options); }); _this.onRejectTaskExecution(function (options) { impl.s12yOnRejectTaskExecution(options); }); return _this; } RenderSequenceImpl.prototype.registerRenderEngine = function registerRenderEngine(renderEngine) { this._engine = renderEngine; }; /** * @implements RenderSequenceInternalAPI#triggerRenderSequence */ RenderSequenceImpl.prototype.triggerRenderSequence = function triggerRenderSequence(options) { var _this2 = this; this._currentRenderContext = {}; this._s12yStartRenderSequence(options); return this._engine.process(options).then(function (result) { _this2._s12yResolveRenderSequence(options); return result; }).catch(function (error) { _this2._s12yResolveRenderSequence(options); throw error; }); }; /** * @private * @function _s12yStartRenderSequence * @description Start tracking the widget render time by creating a current render object * @param {Object} options * @param {number} options.renderId - the current render ID that is being executed */ RenderSequenceImpl.prototype._s12yStartRenderSequence = function _s12yStartRenderSequence(options) { try { var contentInfo = this._s12yAPI.getContentInfo(); if (contentInfo) { var s12ySQLInfo = contentInfo.getData(RenderSequenceImpl.S12Y_SQL_INFO); if (!s12ySQLInfo) { //TODO:Seems out of place to access DataQueryExecution inside render sequence //see if there is a better way to access this //ServiceabilitySQLInfo could be used in other render tasks in theory var queryExecution = this.content.getFeature('DataQueryExecution'); var visApi = this.content.getFeature('WidgetAPI.deprecated').getVisApi(); s12ySQLInfo = new ServiceabilitySQLInfo(visApi, queryExecution); contentInfo.setData(RenderSequenceImpl.S12Y_SQL_INFO, s12ySQLInfo); } var s12yRenderingInfo = contentInfo.getData(RenderSequenceImpl.S12Y_RENDERING_INFO); if (!s12yRenderingInfo) { s12yRenderingInfo = new ServiceabilityRenderingInfo(this._logger); contentInfo.setData(RenderSequenceImpl.S12Y_RENDERING_INFO, s12yRenderingInfo); } var renderingInfo = s12yRenderingInfo.getCurrentRendering(); if (renderingInfo === undefined) { renderingInfo = new RenderingInfo({ renderId: options.renderId }); s12yRenderingInfo.setCurrentRendering(renderingInfo); } else { renderingInfo.registerSequenceId(options.renderId); } } else { this._logger.info('Serviceability feature is not enabled'); } } catch (error) { this._logger.error('Failed to track RenderingInfo for renderId [' + options.renderId + ']', error); } }; /** * @private * @function s12yResolveRenderSequence * @description Resolve the tracking for RenderInfo * @param {Object} options * @param {number} options.renderId - the current render ID that is being executed */ RenderSequenceImpl.prototype._s12yResolveRenderSequence = function _s12yResolveRenderSequence(options) { try { var contentInfo = this._s12yAPI.getContentInfo(); if (contentInfo) { var s12yRenderingInfo = contentInfo.getData(RenderSequenceImpl.S12Y_RENDERING_INFO); var renderingInfo = s12yRenderingInfo.getCurrentRendering(); if (renderingInfo && renderingInfo.getLastSequenceId() === options.renderId) { renderingInfo.setEndTime(Date.now()); if (renderingInfo.isWithData()) { s12yRenderingInfo.setLastRendering(renderingInfo); } s12yRenderingInfo.setCurrentRendering(undefined); } } } catch (error) { this._logger.error('Failed to track RenderingInfo for renderId [' + options.renderId + ']', error); } }; RenderSequenceImpl.prototype.getCurrentRenderContext = function getCurrentRenderContext(taskId) { return this._currentRenderContext[taskId]; }; /** * TODO: remove the call to _isStepComplete as a task should be processed only when it needs * @implements RenderSequenceInternalAPI#startTaskExecution */ RenderSequenceImpl.prototype.startTaskExecution = function startTaskExecution(taskInfo) { var taskId = taskInfo.task.instance.getId(); try { if (taskInfo.task.instance._isStepComplete(taskInfo.renderContext, taskId) === true) { this._logger.info('execution of task [' + taskId + '] is ignored for s12y as it is already complete'); } else { this._setSQLFetchParams(taskInfo.renderContext); var taskRenderContext = this._createTaskRenderContext(taskInfo.renderContext); this.invokeCallbacks(RenderSequenceImpl.START_TASK_EXECUTION, { renderContext: taskRenderContext, taskId: taskId }); } } catch (error) { this._logger.error('fail to check if task [' + taskId + '] is complete', error); } return taskInfo.task.instance.process(taskInfo.renderContext); }; /** * @implements RenderSequenceInternalAPI#resolveTaskExecution */ RenderSequenceImpl.prototype.resolveTaskExecution = function resolveTaskExecution(taskInfo) { var taskId = taskInfo.task.instance.getId(); var taskRenderContext = this._createTaskRenderContext(taskInfo.renderContext); this.invokeCallbacks(RenderSequenceImpl.RESOLVE_TASK_EXECUTION, { renderContext: taskRenderContext, taskId: taskId }); taskInfo.taskExecution.resolve(); this._currentRenderContext[taskInfo.task.id] = taskRenderContext; }; /** * @implements RenderSequenceInternalAPI#rejectTaskExecution */ RenderSequenceImpl.prototype.rejectTaskExecution = function rejectTaskExecution(taskInfo) { var taskRenderContext = this._createTaskRenderContext(taskInfo.renderContext); this.invokeCallbacks(RenderSequenceImpl.REJECT_TASK_EXECUTION, { error: taskInfo.error, renderContext: taskRenderContext, taskId: taskInfo.task.instance.getId() }); taskInfo.taskExecution.reject(taskInfo.error); this._currentRenderContext[taskInfo.task.id] = taskRenderContext; }; /** * @implements RenderSequenceAPI#onStartTaskExecution */ RenderSequenceImpl.prototype.onStartTaskExecution = function onStartTaskExecution(method) { this.registerCallback(RenderSequenceImpl.START_TASK_EXECUTION, method); }; /** * @implements RenderSequenceAPI#onSuccessEndTaskExecution */ RenderSequenceImpl.prototype.onResolveTaskExecution = function onResolveTaskExecution(method) { this.registerCallback(RenderSequenceImpl.RESOLVE_TASK_EXECUTION, method); }; /** * @implements RenderSequenceAPI#onFailureEndTaskExecution */ RenderSequenceImpl.prototype.onRejectTaskExecution = function onRejectTaskExecution(method) { this.registerCallback(RenderSequenceImpl.REJECT_TASK_EXECUTION, method); }; /** * @implements RenderSequenceAPI#registerRenderStepProvider */ RenderSequenceImpl.prototype.registerRenderStepProvider = function registerRenderStepProvider(provider) { if (provider) { if (typeof provider.getRenderStepList !== 'function') { throw new Error('the provide must implement "getRenderStepList()" '); } this._renderStepProviders.push(provider); } }; /** * @implements RenderSequenceAPI#getProvidersRenderStepList */ RenderSequenceImpl.prototype.getProvidersRenderStepList = function getProvidersRenderStepList() { var _this3 = this; var steps = []; this._renderStepProviders.forEach(function (provider) { try { var extraSteps = provider.getRenderStepList(); if (Array.isArray(extraSteps)) { steps.push.apply(steps, extraSteps); } else { _this3._logger.warn('Provide render steps are ignored. The render step provider did not return an array. '); } } catch (e) { _this3._logger.error('An error while getting the render step list from the provider', e); } }); return steps; }; /** * creates an instance of RenderContext with the API method of {@link RenderContextAPI} * @param {Object} renderContext - sequence renderContext */ RenderSequenceImpl.prototype._createTaskRenderContext = function _createTaskRenderContext(renderContext) { var renderContextImpl = new RenderContextImpl({ logger: this._logger, renderContext: renderContext }); var api = APIFactory.createAPI(renderContextImpl, [RenderContextAPI]); return api; }; /** * Callback to task execution start * @param {RenderContextAPI} payload */ RenderSequenceImpl.prototype.s12yOnStartTaskExecution = function s12yOnStartTaskExecution(payload) { var s12yInfo = this._s12yAPI.getContentInfo(); if (!s12yInfo) { this._logger.info('Serviceability feature is not enabled'); } else { var sequenceId = payload.renderContext.getSequenceId(); var renderingInfo = s12yInfo.getData(RenderSequenceImpl.S12Y_RENDERING_INFO); var currentRender = renderingInfo.getCurrentRendering(); if (currentRender) { currentRender.setWithData(true); var renderSequenceInfo = currentRender.getRenderSequenceWithData(); if (this._isNewerSequence(sequenceId, renderSequenceInfo)) { renderSequenceInfo = new RenderSequenceInfo({ id: sequenceId }); renderSequenceInfo.addTaskInfo({ taskId: payload.taskId }); currentRender.setRenderSequenceWithData(renderSequenceInfo); } } } }; /** * Callback to task resolution * TODO: introduce a generic way to get task providing their own result * @param {RenderContextAPI} payload */ RenderSequenceImpl.prototype.s12yOnResolveTaskExecution = function s12yOnResolveTaskExecution(payload) { var taskExecInfo = this._setTaskExecEndTime(payload); this._setQueryFeedbackSQLResult(payload.renderContext.getData(payload.taskId)); if (taskExecInfo) { this._setDataResult(taskExecInfo, payload.renderContext.getData(payload.taskId)); } }; /** * Callback to task rejection * TODO: remove the assumption the task is a data task * @param {RenderContextAPI} payload */ RenderSequenceImpl.prototype.s12yOnRejectTaskExecution = function s12yOnRejectTaskExecution(payload) { var taskExecInfo = this._setTaskExecEndTime(payload); if (taskExecInfo) { this._setTaskExecError(taskExecInfo, payload.error); } }; RenderSequenceImpl.prototype._setQueryFeedbackSQLResult = function _setQueryFeedbackSQLResult(data) { var contentInfo = this._s12yAPI.getContentInfo(); if (contentInfo) { var sqlInfo = contentInfo.getData(RenderSequenceImpl.S12Y_SQL_INFO); if (!_.isEmpty(data)) { data.getQueryResultIdList().forEach(function (id) { var queryResult = data.getResult(id); sqlInfo.widgetsLastCognosQuery = queryResult.getPropertyValue('QueryFeedback.cognosSQL'); sqlInfo.widgetsLastNativeQuery = queryResult.getPropertyValue('QueryFeedback.nativeSQL'); sqlInfo.widgetsLastMDXQuery = queryResult.getPropertyValue('QueryFeedback.MDX'); }); } } else { this._logger.info('Serviceability feature is not enabled'); } }; RenderSequenceImpl.prototype._setSQLFetchParams = function _setSQLFetchParams(renderContext) { var contentInfo = this._s12yAPI.getContentInfo(); if (contentInfo) { renderContext.extraInfo = renderContext.extraInfo || {}; var sqlInfo = contentInfo.getData(RenderSequenceImpl.S12Y_SQL_INFO); if (sqlInfo.shouldFetchQuery) { renderContext.extraInfo.dataQueryParams = { qfb: 'nativeCommandText,nativeCommandType,CognosCommandText' }; } } else { this._logger.info('Serviceability feature is not enabled'); } }; /** * @private * @param {integer} startedSequenceId * @param {RenderSequenceInfo} s12ySequenceInfo * @returns {boolean} true if s12ySequenceInfo is undefined or the startedSequenceId is greater than the s12ySequenceInfo one */ RenderSequenceImpl.prototype._isNewerSequence = function _isNewerSequence(startedSequenceId, s12ySequenceInfo) { return !s12ySequenceInfo || startedSequenceId > s12ySequenceInfo.getId(); }; /** * sets the task end time if needed * @private * @param {RenderContextAPI} options - callback payload * @returns {RenderTaskExecInfo} - the task exec info or undefined if none is to be updated */ RenderSequenceImpl.prototype._setTaskExecEndTime = function _setTaskExecEndTime(options) { var taskExecInfo = void 0; var s12yInfo = this._s12yAPI.getContentInfo(); if (!s12yInfo) { this._logger.info('Serviceability feature is not enabled'); } else { var sequenceId = options.renderContext.getSequenceId(); var s12yRenderingInfo = s12yInfo.getData(RenderSequenceImpl.S12Y_RENDERING_INFO); var currentRenderInfo = s12yRenderingInfo.getCurrentRendering(); if (currentRenderInfo) { var renderSequenceInfo = currentRenderInfo.getRenderSequenceWithData(); if (renderSequenceInfo && sequenceId === renderSequenceInfo.getId()) { taskExecInfo = renderSequenceInfo.getTaskInfo(options.taskId); taskExecInfo.setEndTime(); } else { this._logger.info('s12y - setting end time - task [' + options.taskId + '] sequence ' + sequenceId + ' from is ignored by the registered s12y sequence info', renderSequenceInfo); } } } return taskExecInfo; }; /** * creates an error object and sets it in the taskExecInfo * TODO: there should be only one logic to generate the error object; there is one in VisRenderSequence and one here * @param {RenderTaskExecInfo} taskExecInfo * @param {Object} error */ RenderSequenceImpl.prototype._setTaskExecError = function _setTaskExecError(taskExecInfo, error) { var msg = 'dwErrorRenderingVisualization'; if (error) { if (error.msg) { msg = error.msg; } else if (error.message) { msg = error.message; } } var errorInfo = error ? error.errorInfo : undefined; taskExecInfo.setError(new APIError({ msg: msg, params: { errorInfo: errorInfo } })); if (errorInfo && typeof errorInfo.getResponseHeader === 'function') { taskExecInfo.addRequestTimeInfo(errorInfo.getResponseHeader('x-ca-requesttime')); } }; /** * set data result; create a data with a toJSON method to make sure to grab the values only when needed * @param {RenderTaskExecInfo} taskExecInfo * @param {QueryResultObject} data */ RenderSequenceImpl.prototype._setDataResult = function _setDataResult(taskExecInfo, data) { if (taskExecInfo && !_.isEmpty(data)) { data.getQueryResultIdList().forEach(function (id) { var queryResult = data.getResult(id); var requestTime = queryResult.getPropertyValue('RequestTime.internal'); taskExecInfo.addRequestTimeInfo(requestTime); }); var taskResults = { toJSON: function toJSON() { var result = []; data.getQueryResultIdList().forEach(function (id) { var queryResult = data.getResult(id); result.push({ 'spec': JSON.parse(queryResult.getPropertyValue('QuerySpec.internal')), 'data': JSON.parse(queryResult.getPropertyValue('RawData.internal')), requestTime: queryResult.getPropertyValue('RequestTime.internal') }); }); return result; } }; taskExecInfo.setData('queryResults', taskResults); } }; return RenderSequenceImpl; }(CallbackInvoker), _class.START_TASK_EXECUTION = 'startTaskExecution', _class.RESOLVE_TASK_EXECUTION = 'resolveTaskExecution', _class.REJECT_TASK_EXECUTION = 'rejectTaskExecution', _class.LAST_RENDER_WITH_DATA = 'lastRenderingWithDataRequest', _class.S12Y_RENDERING_INFO = 'ServiceabilityRenderingInfo', _class.S12Y_SQL_INFO = 'ServiceabilitySQLInfo', _temp); return RenderSequenceImpl; }); //# sourceMappingURL=RenderSequenceImpl.js.map