| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /* global define, module, require, exports */ |
| |
| (function (root, factory) { |
| if (typeof define === 'function' && define.amd) { |
| define(['jquery', |
| 'd3', |
| 'nf.ErrorHandler', |
| 'nf.Common', |
| 'nf.Dialog', |
| 'nf.Storage', |
| 'nf.Client', |
| 'nf.Settings', |
| 'nf.UniversalCapture', |
| 'nf.CustomUi', |
| 'nf.CanvasUtils', |
| 'nf.Processor'], |
| function ($, d3, nfErrorHandler, nfCommon, nfDialog, nfStorage, nfClient, nfSettings, nfUniversalCapture, nfCustomUi, nfCanvasUtils, nfProcessor) { |
| return (nf.ControllerService = factory($, d3, nfErrorHandler, nfCommon, nfDialog, nfStorage, nfClient, nfSettings, nfUniversalCapture, nfCustomUi, nfCanvasUtils, nfProcessor)); |
| }); |
| } else if (typeof exports === 'object' && typeof module === 'object') { |
| module.exports = (nf.ControllerService = |
| factory(require('jquery'), |
| require('d3'), |
| require('nf.ErrorHandler'), |
| require('nf.Common'), |
| require('nf.Dialog'), |
| require('nf.Storage'), |
| require('nf.Client'), |
| require('nf.Settings'), |
| require('nf.UniversalCapture'), |
| require('nf.CustomUi'), |
| require('nf.CanvasUtils'), |
| require('nf.Processor'))); |
| } else { |
| nf.ControllerService = factory(root.$, |
| root.d3, |
| root.nf.ErrorHandler, |
| root.nf.Common, |
| root.nf.Dialog, |
| root.nf.Storage, |
| root.nf.Client, |
| root.nf.Settings, |
| root.nf.UniversalCapture, |
| root.nf.CustomUi, |
| root.nf.CanvasUtils, |
| root.nf.Processor); |
| } |
| }(this, function ($, d3, nfErrorHandler, nfCommon, nfDialog, nfStorage, nfClient, nfSettings, nfUniversalCapture, nfCustomUi, nfCanvasUtils, nfProcessor) { |
| 'use strict'; |
| |
| var nfControllerServices, nfReportingTask; |
| |
| var config = { |
| edit: 'edit', |
| readOnly: 'read-only', |
| serviceOnly: 'SERVICE_ONLY', |
| serviceAndReferencingComponents: 'SERVICE_AND_REFERENCING_COMPONENTS', |
| urls: { |
| api: '../nifi-api' |
| } |
| }; |
| |
| /** |
| * Determines whether the user has made any changes to the controller service configuration |
| * that needs to be saved. |
| */ |
| var isSaveRequired = function () { |
| var entity = $('#controller-service-configuration').data('controllerServiceDetails'); |
| |
| // determine if any controller service settings have changed |
| |
| if ($('#controller-service-name').val() !== entity.component['name']) { |
| return true; |
| } |
| if ($('#controller-service-comments').val() !== entity.component['comments']) { |
| return true; |
| } |
| |
| // defer to the properties |
| return $('#controller-service-properties').propertytable('isSaveRequired'); |
| }; |
| |
| /** |
| * Marshals the data that will be used to update the contr oller service's configuration. |
| */ |
| var marshalDetails = function () { |
| // properties |
| var properties = $('#controller-service-properties').propertytable('marshalProperties'); |
| |
| // create the controller service dto |
| var controllerServiceDto = {}; |
| controllerServiceDto['id'] = $('#controller-service-id').text(); |
| controllerServiceDto['name'] = $('#controller-service-name').val(); |
| controllerServiceDto['comments'] = $('#controller-service-comments').val(); |
| |
| // set the properties |
| if ($.isEmptyObject(properties) === false) { |
| controllerServiceDto['properties'] = properties; |
| } |
| |
| // create the controller service entity |
| var controllerServiceEntity = {}; |
| controllerServiceEntity['disconnectedNodeAcknowledged'] = nfStorage.isDisconnectionAcknowledged(); |
| controllerServiceEntity['component'] = controllerServiceDto; |
| |
| // return the marshaled details |
| return controllerServiceEntity; |
| }; |
| |
| /** |
| * Validates the specified details. |
| * |
| * @argument {object} details The details to validate |
| */ |
| var validateDetails = function (details) { |
| return true; |
| }; |
| |
| /** |
| * Reloads the specified controller service if we have read permissions. It's referencing and referenced |
| * components are NOT reloaded. |
| * |
| * @param {jQuery} serviceTable |
| * @param {string} id |
| */ |
| var reloadControllerService = function (serviceTable, id) { |
| // get the table and update the row accordingly |
| var controllerServiceGrid = serviceTable.data('gridInstance'); |
| var controllerServiceData = controllerServiceGrid.getData(); |
| var controllerServiceEntity = controllerServiceData.getItemById(id); |
| |
| // this may happen if controller service A references another controller |
| // service B that has been removed. attempting to enable/disable/remove A |
| // will attempt to reload B which is no longer a known service. also ensure |
| // we have permissions to reload the service |
| if (nfCommon.isUndefined(controllerServiceEntity) || controllerServiceEntity.permissions.canRead === false) { |
| return $.Deferred(function (deferred) { |
| deferred.reject(); |
| }).promise(); |
| } |
| |
| return $.ajax({ |
| type: 'GET', |
| url: controllerServiceEntity.uri, |
| dataType: 'json' |
| }).done(function (response) { |
| renderControllerService(serviceTable, response); |
| }).fail(nfErrorHandler.handleAjaxError); |
| }; |
| |
| /** |
| * Renders the specified controller service. |
| * |
| * @param {object} serviceTable |
| * @param {object} controllerServiceEntity |
| */ |
| var renderControllerService = function (serviceTable, controllerServiceEntity) { |
| // get the table and update the row accordingly |
| var controllerServiceGrid = serviceTable.data('gridInstance'); |
| var controllerServiceData = controllerServiceGrid.getData(); |
| var currentControllerServiceEntity = controllerServiceData.getItemById(controllerServiceEntity.id); |
| controllerServiceData.updateItem(controllerServiceEntity.id, $.extend({ |
| type: 'ControllerService', |
| bulletins: currentControllerServiceEntity.bulletins |
| }, controllerServiceEntity)); |
| }; |
| |
| /** |
| * Reloads the specified controller services and all of its referencing |
| * and referenced components. |
| * |
| * @param {jQuery} serviceTable |
| * @param {type} controllerService |
| */ |
| var reloadControllerServiceAndReferencingComponents = function (serviceTable, controllerService) { |
| reloadControllerService(serviceTable, controllerService.id).done(function (response) { |
| reloadControllerServiceReferences(serviceTable, response.component); |
| }); |
| }; |
| |
| /** |
| * Reloads components that reference this controller service as well as |
| * other services that this controller service references. |
| * |
| * @param {jQuery} serviceTable |
| * @param {object} controllerService |
| */ |
| var reloadControllerServiceReferences = function (serviceTable, controllerService) { |
| // reload all dependent processors if they are currently visible |
| $.each(controllerService.referencingComponents, function (_, referencingComponentEntity) { |
| // ensure we can read the referencing component prior to reloading |
| if (referencingComponentEntity.permissions.canRead === false) { |
| return; |
| } |
| |
| var reference = referencingComponentEntity.component; |
| if (reference.referenceType === 'Processor') { |
| // reload the processor on the canvas if appropriate |
| if (nfCanvasUtils.getGroupId() === reference.groupId) { |
| nfProcessor.reload(reference.id); |
| } |
| |
| // update the current active thread count |
| $('div.' + reference.id + '-active-threads').text(reference.activeThreadCount); |
| |
| // update the current state of this processor |
| var referencingComponentState = $('div.' + reference.id + '-state'); |
| if (referencingComponentState.length) { |
| updateReferencingSchedulableComponentState(referencingComponentState, reference); |
| } |
| } else if (reference.referenceType === 'ReportingTask') { |
| // reload the referencing reporting tasks |
| nfReportingTask.reload(reference.id); |
| |
| // update the current active thread count |
| $('div.' + reference.id + '-active-threads').text(reference.activeThreadCount); |
| |
| // update the current state of this reporting task |
| var referencingComponentState = $('div.' + reference.id + '-state'); |
| if (referencingComponentState.length) { |
| updateReferencingSchedulableComponentState(referencingComponentState, reference); |
| } |
| } else { |
| // reload the referencing services |
| reloadControllerService(serviceTable, reference.id); |
| |
| // update the current state of this service |
| var referencingComponentState = $('div.' + reference.id + '-state'); |
| if (referencingComponentState.length) { |
| updateReferencingServiceState(referencingComponentState, reference); |
| } |
| |
| // consider it's referencing components if appropriate |
| if (reference.referenceCycle === false) { |
| reloadControllerServiceReferences(serviceTable, reference); |
| } |
| } |
| }); |
| |
| // see if this controller service references another controller service |
| // in order to update the referenced service referencing components |
| nfControllerService.reloadReferencedServices(serviceTable, controllerService); |
| }; |
| |
| /** |
| * Adds a border to the controller service referencing components if necessary. |
| * |
| * @argument {jQuery} referenceContainer |
| */ |
| var updateReferencingComponentsBorder = function (referenceContainer) { |
| // determine if it is too big |
| var tooBig = referenceContainer.get(0).scrollHeight > Math.round(referenceContainer.innerHeight()) || |
| referenceContainer.get(0).scrollWidth > Math.round(referenceContainer.innerWidth()); |
| |
| // draw the border if necessary |
| if (referenceContainer.is(':visible') && tooBig) { |
| referenceContainer.css('border-width', '1px'); |
| } else { |
| referenceContainer.css('border-width', '0px'); |
| } |
| }; |
| |
| /** |
| * Updates the specified bulletinIcon with the specified bulletins if necessary. |
| * |
| * @param {array} bulletins |
| * @param {jQuery} bulletinIcon |
| */ |
| var updateBulletins = function (bulletins, bulletinIcon) { |
| var currentBulletins = bulletinIcon.data('bulletins'); |
| |
| // update the bulletins if necessary |
| if (nfCommon.doBulletinsDiffer(currentBulletins, bulletins)) { |
| bulletinIcon.data('bulletins', bulletins); |
| |
| // format the new bulletins |
| var formattedBulletins = nfCommon.getFormattedBulletins(bulletins); |
| |
| // if there are bulletins update them |
| if (bulletins.length > 0) { |
| var list = nfCommon.formatUnorderedList(formattedBulletins); |
| |
| // update existing tooltip or initialize a new one if appropriate |
| if (bulletinIcon.data('qtip')) { |
| bulletinIcon.qtip('option', 'content.text', list); |
| } else { |
| bulletinIcon.addClass('has-bulletins').show().qtip($.extend({}, |
| nfCanvasUtils.config.systemTooltipConfig, |
| { |
| content: list |
| })); |
| } |
| } else if (bulletinIcon.data('qtip')) { |
| bulletinIcon.removeClass('has-bulletins').removeData('bulletins').hide().qtip('api').destroy(true); |
| } |
| } |
| }; |
| |
| /** |
| * Updates the referencingComponentState using the specified referencingComponent. |
| * |
| * @param {jQuery} referencingComponentState |
| * @param {object} referencingComponent |
| */ |
| var updateReferencingSchedulableComponentState = function (referencingComponentState, referencingComponent) { |
| referencingComponentState.removeClass('disabled stopped running invalid').addClass(function () { |
| var icon = $(this); |
| |
| var state = referencingComponent.state.toLowerCase(); |
| if (state === 'stopped' && !nfCommon.isEmpty(referencingComponent.validationErrors)) { |
| state = 'invalid'; |
| |
| // add tooltip for the warnings |
| var list = nfCommon.formatUnorderedList(referencingComponent.validationErrors); |
| if (icon.data('qtip')) { |
| icon.qtip('option', 'content.text', list); |
| } else { |
| icon.qtip($.extend({}, |
| nfCanvasUtils.config.systemTooltipConfig, |
| { |
| content: list |
| })); |
| } |
| } else if (icon.data('qtip')) { |
| icon.qtip('api').destroy(true); |
| } |
| return state; |
| }); |
| }; |
| |
| /** |
| * Updates the referencingServiceState using the specified referencingService. |
| * |
| * @param {jQuery} referencingServiceState |
| * @param {object} referencingService |
| */ |
| var updateReferencingServiceState = function (referencingServiceState, referencingService) { |
| referencingServiceState.removeClass('disabled enabled invalid').addClass(function () { |
| var icon = $(this); |
| |
| var state = referencingService.state === 'ENABLED' ? 'enabled' : 'disabled'; |
| if (state === 'disabled' && !nfCommon.isEmpty(referencingService.validationErrors)) { |
| state = 'invalid'; |
| |
| // add tooltip for the warnings |
| var list = nfCommon.formatUnorderedList(referencingService.validationErrors); |
| if (icon.data('qtip')) { |
| icon.qtip('option', 'content.text', list); |
| } else { |
| icon.qtip($.extend({}, |
| nfCanvasUtils.config.systemTooltipConfig, |
| { |
| content: list |
| })); |
| } |
| } else if (icon.data('qtip')) { |
| icon.qtip('api').destroy(true); |
| } |
| return state; |
| }); |
| }; |
| |
| /** |
| * Updates the bulletins for all referencing components. |
| * |
| * @param {array} bulletins |
| */ |
| var updateReferencingComponentBulletins = function (bulletins) { |
| var bulletinsBySource = d3.nest() |
| .key(function (d) { |
| return d.sourceId; |
| }) |
| .map(bulletins, d3.map); |
| |
| bulletinsBySource.each(function (sourceBulletins, sourceId) { |
| $('div.' + sourceId + '-bulletins').each(function () { |
| updateBulletins(sourceBulletins, $(this)); |
| }); |
| }); |
| }; |
| |
| /** |
| * Adds the specified reference for this controller service. |
| * |
| * @param {jQuery} serviceTable |
| * @param {jQuery} referenceContainer |
| * @param {object} controllerServiceEntity |
| */ |
| var createReferencingComponents = function (serviceTable, referenceContainer, controllerServiceEntity) { |
| |
| if (controllerServiceEntity.permissions.canRead === false) { |
| referenceContainer.append('<div class="unset">Unauthorized</div>'); |
| return; |
| } |
| |
| var referencingComponents = controllerServiceEntity.component.referencingComponents; |
| if (nfCommon.isEmpty(referencingComponents)) { |
| referenceContainer.append('<div class="unset">No referencing components.</div>'); |
| return; |
| } |
| |
| // toggles the visibility of a container |
| var toggle = function (twist, container) { |
| if (twist.hasClass('expanded')) { |
| twist.removeClass('expanded').addClass('collapsed'); |
| container.hide(); |
| } else { |
| twist.removeClass('collapsed').addClass('expanded'); |
| container.show(); |
| } |
| }; |
| |
| var processors = $('<ul class="referencing-component-listing clear"></ul>'); |
| var services = $('<ul class="referencing-component-listing clear"></ul>'); |
| var tasks = $('<ul class="referencing-component-listing clear"></ul>'); |
| var unauthorized = $('<ul class="referencing-component-listing clear"></ul>'); |
| $.each(referencingComponents, function (_, referencingComponentEntity) { |
| // check the access policy for this referencing component |
| if (referencingComponentEntity.permissions.canRead === false) { |
| var unauthorizedReferencingComponent = $('<div class="unset"></div>').text(referencingComponentEntity.id); |
| unauthorized.append(unauthorizedReferencingComponent); |
| } else { |
| var referencingComponent = referencingComponentEntity.component; |
| |
| if (referencingComponent.referenceType === 'Processor') { |
| var processorLink = $('<span class="referencing-component-name link"></span>').text(referencingComponent.name).on('click', function () { |
| // show the component |
| nfCanvasUtils.showComponent(referencingComponent.groupId, referencingComponent.id); |
| |
| // close the dialog and shell |
| referenceContainer.closest('.dialog').modal('hide'); |
| $('#shell-close-button').click(); |
| }); |
| |
| // state |
| var processorState = $('<div class="referencing-component-state"></div>').addClass(referencingComponent.id + '-state'); |
| updateReferencingSchedulableComponentState(processorState, referencingComponent); |
| |
| // bulletin |
| var processorBulletins = $('<div class="referencing-component-bulletins"></div>').addClass(referencingComponent.id + '-bulletins'); |
| if (!nfCommon.isEmpty(referencingComponentEntity.bulletins)) { |
| updateBulletins(referencingComponentEntity.bulletins, processorBulletins); |
| } |
| |
| // type |
| var processorType = $('<span class="referencing-component-type"></span>').text(referencingComponent.type); |
| |
| // active thread count |
| var processorActiveThreadCount = $('<span class="referencing-component-active-thread-count"></span>').addClass(referencingComponent.id + '-active-threads'); |
| if (nfCommon.isDefinedAndNotNull(referencingComponent.activeThreadCount) && referencingComponent.activeThreadCount > 0) { |
| processorActiveThreadCount.text('(' + referencingComponent.activeThreadCount + ')'); |
| } |
| |
| // processor |
| var processorItem = $('<li></li>').append(processorState).append(processorBulletins).append(processorLink).append(processorType).append(processorActiveThreadCount); |
| processors.append(processorItem); |
| } else if (referencingComponent.referenceType === 'ControllerService') { |
| var serviceLink = $('<span class="referencing-component-name link"></span>').text(referencingComponent.name).on('click', function () { |
| var controllerServiceGrid = serviceTable.data('gridInstance'); |
| var controllerServiceData = controllerServiceGrid.getData(); |
| |
| // select the selected row |
| var row = controllerServiceData.getRowById(referencingComponent.id); |
| controllerServiceGrid.setSelectedRows([row]); |
| controllerServiceGrid.scrollRowIntoView(row); |
| |
| // close the dialog and shell |
| referenceContainer.closest('.dialog').modal('hide'); |
| }); |
| |
| // container for this service's references |
| var referencingServiceReferencesContainer = $('<div class="referencing-component-references hidden"></div>'); |
| var serviceTwist = $('<div class="service expansion-button collapsed pointer"></div>').on('click', function () { |
| if (serviceTwist.hasClass('collapsed')) { |
| // create the markup for the references |
| if (referencingComponent.referenceCycle === true) { |
| referencingServiceReferencesContainer.append('<div class="unset">Reference cycle detected.</div>'); |
| } else { |
| var controllerServiceGrid = serviceTable.data('gridInstance'); |
| var controllerServiceData = controllerServiceGrid.getData(); |
| |
| // get the controller service and expand its referencing services |
| getControllerService(referencingComponent.id, controllerServiceData).done(function (controllerServiceEntity) { |
| createReferencingComponents(serviceTable, referencingServiceReferencesContainer, controllerServiceEntity); |
| }); |
| } |
| } else { |
| referencingServiceReferencesContainer.empty(); |
| } |
| |
| // toggle visibility |
| toggle(serviceTwist, referencingServiceReferencesContainer); |
| |
| // update borders as necessary |
| updateReferencingComponentsBorder(referenceContainer); |
| }); |
| |
| // state |
| var serviceState = $('<div class="referencing-component-state"></div>').addClass(referencingComponent.id + '-state'); |
| updateReferencingServiceState(serviceState, referencingComponent); |
| |
| // bulletin |
| var serviceBulletins = $('<div class="referencing-component-bulletins"></div>').addClass(referencingComponent.id + '-bulletins'); |
| if (!nfCommon.isEmpty(referencingComponentEntity.bulletins)) { |
| updateBulletins(referencingComponentEntity.bulletins, serviceBulletins); |
| } |
| |
| // type |
| var serviceType = $('<span class="referencing-component-type"></span>').text(referencingComponent.type); |
| |
| // service |
| var serviceItem = $('<li></li>').append(serviceTwist).append(serviceState).append(serviceBulletins).append(serviceLink).append(serviceType).append(referencingServiceReferencesContainer); |
| |
| services.append(serviceItem); |
| } else if (referencingComponent.referenceType === 'ReportingTask') { |
| var reportingTaskLink = $('<span class="referencing-component-name link"></span>').text(referencingComponent.name).on('click', function () { |
| var reportingTaskGrid = $('#reporting-tasks-table').data('gridInstance'); |
| var reportingTaskData = reportingTaskGrid.getData(); |
| |
| // select the selected row |
| var row = reportingTaskData.getRowById(referencingComponent.id); |
| reportingTaskGrid.setSelectedRows([row]); |
| reportingTaskGrid.scrollRowIntoView(row); |
| |
| // select the reporting task tab |
| $('#settings-tabs').find('li:nth-child(3)').click(); |
| |
| // close the dialog and shell |
| referenceContainer.closest('.dialog').modal('hide'); |
| }); |
| |
| // state |
| var reportingTaskState = $('<div class="referencing-component-state"></div>').addClass(referencingComponent.id + '-state'); |
| updateReferencingSchedulableComponentState(reportingTaskState, referencingComponent); |
| |
| // bulletins |
| var reportingTaskBulletins = $('<div class="referencing-component-bulletins"></div>').addClass(referencingComponent.id + '-bulletins'); |
| if (!nfCommon.isEmpty(referencingComponentEntity.bulletins)) { |
| updateBulletins(referencingComponentEntity.bulletins, reportingTaskBulletins); |
| } |
| |
| // type |
| var reportingTaskType = $('<span class="referencing-component-type"></span>').text(nfCommon.substringAfterLast(referencingComponent.type, '.')); |
| |
| // active thread count |
| var reportingTaskActiveThreadCount = $('<span class="referencing-component-active-thread-count"></span>').addClass(referencingComponent.id + '-active-threads'); |
| if (nfCommon.isDefinedAndNotNull(referencingComponent.activeThreadCount) && referencingComponent.activeThreadCount > 0) { |
| reportingTaskActiveThreadCount.text('(' + referencingComponent.activeThreadCount + ')'); |
| } |
| |
| // reporting task |
| var reportingTaskItem = $('<li></li>').append(reportingTaskState).append(reportingTaskBulletins).append(reportingTaskLink).append(reportingTaskType).append(reportingTaskActiveThreadCount); |
| tasks.append(reportingTaskItem); |
| } |
| } |
| }); |
| |
| // create the collapsable listing for each type |
| var createReferenceBlock = function (titleText, list) { |
| if (list.is(':empty')) { |
| list.remove(); |
| return; |
| } |
| |
| var twist = $('<div class="expansion-button expanded"></div>'); |
| var title = $('<span class="referencing-component-title"></span>').text(titleText); |
| var count = $('<span class="referencing-component-count"></span>').text('(' + list.children().length + ')'); |
| |
| // create the reference block |
| $('<div class="referencing-component-block pointer unselectable"></div>').on('click', function () { |
| // toggle this block |
| toggle(twist, list); |
| |
| // update the border if necessary |
| updateReferencingComponentsBorder(referenceContainer); |
| }).append(twist).append(title).append(count).appendTo(referenceContainer); |
| |
| // add the listing |
| list.appendTo(referenceContainer); |
| }; |
| |
| // create blocks for each type of component |
| createReferenceBlock('Processors', processors); |
| createReferenceBlock('Reporting Tasks', tasks); |
| createReferenceBlock('Controller Services', services); |
| createReferenceBlock('Unauthorized', unauthorized); |
| |
| // now that the dom elements are in place, we can show the bulletin icons. |
| $('div.referencing-component-bulletins.has-bulletins').show(); |
| }; |
| |
| /** |
| * Sets whether the specified controller service is enabled. |
| * |
| * @param {jQuery} serviceTable |
| * @param {object} controllerServiceEntity |
| * @param {boolean} enabled |
| * @param {function} pollCondition |
| */ |
| var setEnabled = function (serviceTable, controllerServiceEntity, enabled, pollCondition) { |
| // build the request entity |
| var updateControllerServiceEntity = { |
| 'revision': nfClient.getRevision(controllerServiceEntity), |
| 'disconnectedNodeAcknowledged': nfStorage.isDisconnectionAcknowledged(), |
| 'state': enabled ? 'ENABLED' : 'DISABLED' |
| }; |
| |
| var updated = $.ajax({ |
| type: 'PUT', |
| url: controllerServiceEntity.uri + '/run-status', |
| data: JSON.stringify(updateControllerServiceEntity), |
| dataType: 'json', |
| contentType: 'application/json' |
| }).done(function (response) { |
| renderControllerService(serviceTable, response); |
| }).fail(nfErrorHandler.handleAjaxError); |
| |
| // wait until the polling of each service finished |
| return $.Deferred(function (deferred) { |
| updated.done(function () { |
| if (controllerServiceEntity.permissions.canRead === false) { |
| // Can not use GET request to wait for completion. Just resolve blindly. The PUT request has been finished anyway. |
| deferred.resolve(); |
| return; |
| } |
| |
| var serviceUpdated = pollService(controllerServiceEntity, function (latestControllerServiceEntity, bulletins) { |
| if ($.isArray(bulletins)) { |
| if (enabled) { |
| updateBulletins(bulletins, $('#enable-controller-service-bulletins')); |
| } else { |
| updateBulletins(bulletins, $('#disable-controller-service-bulletins')); |
| } |
| } |
| |
| // the condition is met once the service is (ENABLING or ENABLED)/DISABLED |
| var runStatus = latestControllerServiceEntity.status.runStatus; |
| if (enabled) { |
| return runStatus === 'ENABLING' || runStatus === 'ENABLED'; |
| } else { |
| return runStatus === 'DISABLED'; |
| } |
| }, function (service) { |
| return nfCanvasUtils.queryBulletins([controllerServiceEntity.id]); |
| }, pollCondition); |
| |
| // once the service has updated, resolve and render the updated service |
| serviceUpdated.done(function () { |
| deferred.resolve(); |
| }).fail(function () { |
| deferred.reject(); |
| }); |
| }).fail(function () { |
| deferred.reject(); |
| }); |
| }).promise(); |
| }; |
| |
| /** |
| * Gets the id's of all controller services referencing the specified controller service. |
| * |
| * @param {object} controllerService |
| */ |
| var getReferencingControllerServiceIds = function (controllerService) { |
| var ids = d3.set(); |
| ids.add(controllerService.id); |
| |
| var checkReferencingServices = function (referencingComponents) { |
| $.each(referencingComponents, function (_, referencingComponentEntity) { |
| var referencingComponent = referencingComponentEntity.component; |
| if (referencingComponent.referenceType === 'ControllerService') { |
| // add the id |
| ids.add(referencingComponent.id); |
| |
| // consider it's referencing components if appropriate |
| if (referencingComponent.referenceCycle === false) { |
| checkReferencingServices(referencingComponent.referencingComponents); |
| } |
| } |
| }); |
| }; |
| |
| // check the referencing services |
| checkReferencingServices(controllerService.referencingComponents); |
| return ids; |
| }; |
| |
| /** |
| * Gathers all referencing component revisions. |
| * |
| * @param referencingComponents |
| * @param referencingComponentRevisions |
| * @param serviceOnly - true includes only services, false includes only schedulable components |
| */ |
| var getReferencingComponentRevisions = function (referencingComponents, referencingComponentRevisions, serviceOnly) { |
| // include the revision of each referencing component |
| $.each(referencingComponents, function (_, referencingComponentEntity) { |
| var referencingComponent = referencingComponentEntity.component; |
| |
| if (serviceOnly) { |
| if (referencingComponent.referenceType === 'ControllerService') { |
| referencingComponentRevisions[referencingComponentEntity.id] = nfClient.getRevision(referencingComponentEntity); |
| } |
| } else { |
| if (referencingComponent.referenceType !== 'ControllerService') { |
| referencingComponentRevisions[referencingComponentEntity.id] = nfClient.getRevision(referencingComponentEntity); |
| } |
| } |
| |
| // recurse |
| getReferencingComponentRevisions(referencingComponent.referencingComponents, referencingComponentRevisions, serviceOnly); |
| }); |
| }; |
| |
| /** |
| * Updates the scheduled state of the processors/reporting tasks referencing |
| * the specified controller service. |
| * |
| * @param {jQuery} serviceTable |
| * @param {object} controllerServiceEntity |
| * @param {boolean} running |
| * @param {function} pollCondition |
| */ |
| var updateReferencingSchedulableComponents = function (serviceTable, controllerServiceEntity, running, pollCondition) { |
| var referencingRevisions = {}; |
| getReferencingComponentRevisions(controllerServiceEntity.component.referencingComponents, referencingRevisions, false); |
| |
| var referenceEntity = { |
| 'id': controllerServiceEntity.id, |
| 'state': running ? 'RUNNING' : 'STOPPED', |
| 'referencingComponentRevisions': referencingRevisions, |
| 'disconnectedNodeAcknowledged': nfStorage.isDisconnectionAcknowledged() |
| }; |
| |
| // issue the request to update the referencing components |
| var updated = $.ajax({ |
| type: 'PUT', |
| url: controllerServiceEntity.uri + '/references', |
| data: JSON.stringify(referenceEntity), |
| dataType: 'json', |
| contentType: 'application/json' |
| }).fail(nfErrorHandler.handleAjaxError); |
| |
| // Note: updated revisions will be retrieved after updateReferencingSchedulableComponents is invoked |
| |
| // wait until the polling of each service finished |
| return $.Deferred(function (deferred) { |
| updated.done(function (response) { |
| // update the controller service |
| controllerServiceEntity.component.referencingComponents = response.controllerServiceReferencingComponents; |
| |
| // if we're just starting schedulable components we're done when the update is finished |
| if (running) { |
| deferred.resolve(); |
| } else { |
| // identify all referencing services |
| var services = getReferencingControllerServiceIds(controllerServiceEntity.component); |
| |
| // get the controller service grid |
| var controllerServiceGrid = serviceTable.data('gridInstance'); |
| var controllerServiceData = controllerServiceGrid.getData(); |
| |
| // start polling for each controller service |
| var polling = []; |
| services.each(function (controllerServiceId) { |
| getControllerService(controllerServiceId, controllerServiceData).done(function(controllerServiceEntity) { |
| polling.push(stopReferencingSchedulableComponents(controllerServiceEntity, pollCondition)); |
| }); |
| }); |
| |
| // wait until polling has finished |
| $.when.apply(window, polling).done(function () { |
| deferred.resolve(); |
| }).fail(function () { |
| deferred.reject(); |
| }); |
| } |
| }).fail(function () { |
| deferred.reject(); |
| }); |
| }).promise(); |
| }; |
| |
| /** |
| * Gets the controller service with the specified id. If the service is present in the specified |
| * controllerServiceData it will be used. Otherwise it will query for it. |
| * |
| * @param controllerServiceId service id |
| * @param controllerServiceData service table data |
| * @returns {deferred} the controller service entity |
| */ |
| var getControllerService = function (controllerServiceId, controllerServiceData) { |
| var controllerServiceEntity = controllerServiceData.getItemById(controllerServiceId); |
| if (nfCommon.isDefinedAndNotNull(controllerServiceEntity)) { |
| return $.Deferred(function (deferred) { |
| deferred.resolve(controllerServiceEntity); |
| }); |
| } else { |
| return $.ajax({ |
| type: 'GET', |
| url: '../nifi-api/controller-services/' + encodeURIComponent(controllerServiceId), |
| dataType: 'json' |
| }).fail(nfErrorHandler.handleAjaxError); |
| } |
| }; |
| |
| /** |
| * Polls the specified services referencing components to see if the |
| * specified condition is satisfied. |
| * |
| * @param {object} controllerServiceEntity |
| * @param {function} completeCondition |
| * @param {function} bulletinDeferred |
| * @param {function} pollCondition |
| */ |
| var pollService = function (controllerServiceEntity, completeCondition, bulletinDeferred, pollCondition) { |
| var controllerService = controllerServiceEntity.component; |
| |
| // we want to keep polling until the condition is met |
| return $.Deferred(function (deferred) { |
| var current = 2; |
| var getTimeout = function () { |
| var val = current; |
| |
| // update the current timeout for the next time |
| current = Math.min(current * 2, 4); |
| |
| return val * 1000; |
| }; |
| |
| // polls for the current status of the referencing components |
| var poll = function () { |
| var bulletins = bulletinDeferred(controllerService); |
| var service = $.ajax({ |
| type: 'GET', |
| url: controllerServiceEntity.uri, |
| dataType: 'json' |
| }); |
| |
| $.when(bulletins, service).done(function (bulletinResponse, serviceResult) { |
| var latestControllerServiceEntity = serviceResult[0]; |
| conditionMet(latestControllerServiceEntity, bulletinResponse.bulletinBoard.bulletins); |
| }).fail(function (xhr, status, error) { |
| deferred.reject(); |
| nfErrorHandler.handleAjaxError(xhr, status, error); |
| }); |
| }; |
| |
| // tests to if the condition has been met |
| var conditionMet = function (latestControllerServiceEntity, bulletins) { |
| if (completeCondition(latestControllerServiceEntity, bulletins)) { |
| deferred.resolve(); |
| } else { |
| if (typeof pollCondition === 'function' && pollCondition()) { |
| setTimeout(poll, getTimeout()); |
| } else { |
| deferred.reject(); |
| } |
| } |
| }; |
| |
| // poll for the status of the referencing components |
| bulletinDeferred(controllerService).done(function (response) { |
| conditionMet(controllerServiceEntity, response.bulletinBoard.bulletins); |
| }).fail(function (xhr, status, error) { |
| deferred.reject(); |
| nfErrorHandler.handleAjaxError(xhr, status, error); |
| }); |
| }).promise(); |
| }; |
| |
| /** |
| * Continues to poll the specified controller service until all referencing schedulable |
| * components are stopped (not scheduled and 0 active threads). |
| * |
| * @param {object} controllerServiceEntity |
| * @param {function} pollCondition |
| */ |
| var stopReferencingSchedulableComponents = function (controllerServiceEntity, pollCondition) { |
| // continue to poll the service until all schedulable components have stopped |
| return pollService(controllerServiceEntity, function (latestControllerServiceEntity, bulletins) { |
| var referencingComponents = latestControllerServiceEntity.component.referencingComponents; |
| |
| var stillRunning = false; |
| $.each(referencingComponents, function (_, referencingComponentEntity) { |
| var referencingComponent = referencingComponentEntity.component; |
| if (referencingComponent.referenceType === 'Processor' || referencingComponent.referenceType === 'ReportingTask') { |
| if (referencingComponent.state === 'RUNNING' || referencingComponent.activeThreadCount > 0) { |
| stillRunning = true; |
| } |
| |
| // update the current active thread count |
| $('div.' + referencingComponent.id + '-active-threads').text(referencingComponent.activeThreadCount); |
| |
| // update the current state of this component |
| var referencingComponentState = $('div.' + referencingComponent.id + '-state'); |
| updateReferencingSchedulableComponentState(referencingComponentState, referencingComponent); |
| } |
| }); |
| |
| // query for the bulletins |
| updateReferencingComponentBulletins(bulletins); |
| |
| // condition is met once all referencing are not running |
| return stillRunning === false; |
| }, function (service) { |
| var referencingSchedulableComponents = []; |
| |
| var referencingComponents = service.referencingComponents; |
| $.each(referencingComponents, function (_, referencingComponentEntity) { |
| var referencingComponent = referencingComponentEntity.component; |
| if (referencingComponent.referenceType === 'Processor' || referencingComponent.referenceType === 'ReportingTask') { |
| referencingSchedulableComponents.push(referencingComponent.id); |
| } |
| }); |
| |
| return nfCanvasUtils.queryBulletins(referencingSchedulableComponents); |
| }, pollCondition); |
| }; |
| |
| /** |
| * Continues to poll until all referencing services are enabled. |
| * |
| * @param {object} controllerServiceEntity |
| * @param {function} pollCondition |
| */ |
| var enableReferencingServices = function (controllerServiceEntity, pollCondition) { |
| // continue to poll the service until all referencing services are enabled |
| return pollService(controllerServiceEntity, function (latestControllerServiceEntity, bulletins) { |
| var referencingComponents = latestControllerServiceEntity.component.referencingComponents; |
| |
| var notEnabled = false; |
| $.each(referencingComponents, function (_, referencingComponentEntity) { |
| var referencingComponent = referencingComponentEntity.component; |
| if (referencingComponent.referenceType === 'ControllerService') { |
| if (referencingComponent.state !== 'ENABLING' && referencingComponent.state !== 'ENABLED') { |
| notEnabled = true; |
| } |
| |
| // update the state of the referencing service |
| var referencingServiceState = $('div.' + referencingComponent.id + '-state'); |
| updateReferencingServiceState(referencingServiceState, referencingComponent); |
| } |
| }); |
| |
| // query for the bulletins |
| updateReferencingComponentBulletins(bulletins); |
| |
| // condition is met once all referencing are not disabled |
| return notEnabled === false; |
| }, function (service) { |
| var referencingSchedulableComponents = []; |
| |
| var referencingComponents = service.referencingComponents; |
| $.each(referencingComponents, function (_, referencingComponentEntity) { |
| var referencingComponent = referencingComponentEntity.component; |
| if (referencingComponent.referenceType === 'ControllerService') { |
| referencingSchedulableComponents.push(referencingComponent.id); |
| } |
| }); |
| |
| return nfCanvasUtils.queryBulletins(referencingSchedulableComponents); |
| }, pollCondition); |
| }; |
| |
| /** |
| * Continues to poll until all referencing services are disabled. |
| * |
| * @param {object} controllerServiceEntity |
| * @param {function} pollCondition |
| */ |
| var disableReferencingServices = function (controllerServiceEntity, pollCondition) { |
| // continue to poll the service until all referencing services are disabled |
| return pollService(controllerServiceEntity, function (latestControllerServiceEntity, bulletins) { |
| var referencingComponents = latestControllerServiceEntity.component.referencingComponents; |
| |
| var notDisabled = false; |
| $.each(referencingComponents, function (_, referencingComponentEntity) { |
| var referencingComponent = referencingComponentEntity.component; |
| if (referencingComponent.referenceType === 'ControllerService') { |
| if (referencingComponent.state !== 'DISABLED') { |
| notDisabled = true; |
| } |
| |
| // update the state of the referencing service |
| var referencingServiceState = $('div.' + referencingComponent.id + '-state'); |
| updateReferencingServiceState(referencingServiceState, referencingComponent); |
| } |
| }); |
| |
| // query for the bulletins |
| updateReferencingComponentBulletins(bulletins); |
| |
| // condition is met once all referencing are not enabled |
| return notDisabled === false; |
| }, function (service) { |
| var referencingSchedulableComponents = []; |
| |
| var referencingComponents = service.referencingComponents; |
| $.each(referencingComponents, function (_, referencingComponentEntity) { |
| var referencingComponent = referencingComponentEntity.component; |
| if (referencingComponent.referenceType === 'ControllerService') { |
| referencingSchedulableComponents.push(referencingComponent.id); |
| } |
| }); |
| |
| return nfCanvasUtils.queryBulletins(referencingSchedulableComponents); |
| }, pollCondition); |
| }; |
| |
| /** |
| * Updates the referencing services with the specified state. |
| * |
| * @param {jQuery} serviceTable |
| * @param {object} controllerServiceEntity |
| * @param {boolean} enabled |
| * @param {function} pollCondition |
| */ |
| var updateReferencingServices = function (serviceTable, controllerServiceEntity, enabled, pollCondition) { |
| var referencingRevisions = {}; |
| getReferencingComponentRevisions(controllerServiceEntity.component.referencingComponents, referencingRevisions, true); |
| |
| // build the reference entity |
| var referenceEntity = { |
| 'id': controllerServiceEntity.id, |
| 'state': enabled ? 'ENABLED' : 'DISABLED', |
| 'referencingComponentRevisions': referencingRevisions, |
| 'disconnectedNodeAcknowledged': nfStorage.isDisconnectionAcknowledged() |
| }; |
| |
| // issue the request to update the referencing components |
| var updated = $.ajax({ |
| type: 'PUT', |
| url: controllerServiceEntity.uri + '/references', |
| data: JSON.stringify(referenceEntity), |
| dataType: 'json', |
| contentType: 'application/json' |
| }).fail(nfErrorHandler.handleAjaxError); |
| |
| // Note: updated revisions will be retrieved after updateReferencingServices is invoked |
| |
| // wait unil the polling of each service finished |
| return $.Deferred(function (deferred) { |
| updated.done(function (response) { |
| // update the controller service |
| controllerServiceEntity.component.referencingComponents = response.controllerServiceReferencingComponents; |
| |
| // identify all referencing services |
| var services = getReferencingControllerServiceIds(controllerServiceEntity.component); |
| |
| // get the controller service grid |
| var controllerServiceGrid = serviceTable.data('gridInstance'); |
| var controllerServiceData = controllerServiceGrid.getData(); |
| |
| // start polling for each controller service |
| var polling = []; |
| services.each(function (controllerServiceId) { |
| getControllerService(controllerServiceId, controllerServiceData).done(function(controllerServiceEntity) { |
| if (enabled) { |
| polling.push(enableReferencingServices(controllerServiceEntity, pollCondition)); |
| } else { |
| polling.push(disableReferencingServices(controllerServiceEntity, pollCondition)); |
| } |
| }); |
| }); |
| |
| $.when.apply(window, polling).done(function () { |
| deferred.resolve(); |
| }).fail(function () { |
| deferred.reject(); |
| }); |
| }).fail(function () { |
| deferred.reject(); |
| }); |
| }).promise(); |
| }; |
| |
| /** |
| * Shows the dialog for disabling a controller service. |
| * |
| * @argument {object} controllerService The controller service to disable |
| */ |
| var showDisableControllerServiceDialog = function (serviceTable, controllerServiceEntity) { |
| // populate the disable controller service dialog |
| $('#disable-controller-service-id').text(controllerServiceEntity.id); |
| $('#disable-controller-service-name').text(nfCommon.getComponentName(controllerServiceEntity)); |
| |
| // load the controller referencing components list |
| var referencingComponentsContainer = $('#disable-controller-service-referencing-components'); |
| createReferencingComponents(serviceTable, referencingComponentsContainer, controllerServiceEntity); |
| |
| // build the button model |
| var buttons = [{ |
| buttonText: 'Disable', |
| color: { |
| base: '#728E9B', |
| hover: '#004849', |
| text: '#ffffff' |
| }, |
| handler: { |
| click: function () { |
| disableHandler(serviceTable); |
| } |
| } |
| }, { |
| buttonText: 'Cancel', |
| color: { |
| base: '#E3E8EB', |
| hover: '#C7D2D7', |
| text: '#004849' |
| }, |
| handler: { |
| click: closeModal |
| } |
| }]; |
| |
| // show the dialog |
| $('#disable-controller-service-dialog').modal('setButtonModel', buttons).modal('show'); |
| |
| // load the bulletins |
| nfCanvasUtils.queryBulletins([controllerServiceEntity.id]).done(function (response) { |
| updateBulletins(response.bulletinBoard.bulletins, $('#disable-controller-service-bulletins')); |
| }); |
| |
| // update the border if necessary |
| updateReferencingComponentsBorder(referencingComponentsContainer); |
| }; |
| |
| /** |
| * Shows the dialog for enabling a controller service. |
| * |
| * @param {object} serviceTable |
| * @param {object} controllerService |
| */ |
| var showEnableControllerServiceDialog = function (serviceTable, controllerServiceEntity) { |
| // populate the disable controller service dialog |
| $('#enable-controller-service-id').text(controllerServiceEntity.id); |
| $('#enable-controller-service-name').text(nfCommon.getComponentName(controllerServiceEntity)); |
| |
| // load the controller referencing components list |
| var referencingComponentsContainer = $('#enable-controller-service-referencing-components'); |
| createReferencingComponents(serviceTable, referencingComponentsContainer, controllerServiceEntity); |
| |
| // build the button model |
| var buttons = [{ |
| buttonText: 'Enable', |
| color: { |
| base: '#728E9B', |
| hover: '#004849', |
| text: '#ffffff' |
| }, |
| handler: { |
| click: function () { |
| enableHandler(serviceTable); |
| } |
| } |
| }, { |
| buttonText: 'Cancel', |
| color: { |
| base: '#E3E8EB', |
| hover: '#C7D2D7', |
| text: '#004849' |
| }, |
| handler: { |
| click: closeModal |
| } |
| }]; |
| |
| // show the dialog |
| $('#enable-controller-service-dialog').modal('setButtonModel', buttons).modal('show'); |
| |
| // load the bulletins |
| nfCanvasUtils.queryBulletins([controllerServiceEntity.id]).done(function (response) { |
| updateBulletins(response.bulletinBoard.bulletins, $('#enable-controller-service-bulletins')); |
| }); |
| |
| // update the border if necessary |
| updateReferencingComponentsBorder(referencingComponentsContainer); |
| }; |
| |
| /** |
| * Used to handle closing a modal dialog |
| */ |
| var closeModal = function () { |
| $(this).modal('hide'); |
| }; |
| |
| /** |
| * Handles the disable action of the disable controller service dialog. |
| * |
| * @param {jQuery} serviceTable |
| */ |
| var disableHandler = function (serviceTable) { |
| var disableDialog = $('#disable-controller-service-dialog'); |
| var canceled = false; |
| |
| // only provide a cancel option |
| disableDialog.modal('setButtonModel', [{ |
| buttonText: 'Cancel', |
| color: { |
| base: '#E3E8EB', |
| hover: '#C7D2D7', |
| text: '#004849' |
| }, |
| handler: { |
| click: function () { |
| canceled = true; |
| disableDialog.modal('setButtonModel', []); |
| $('#disable-controller-service-dialog div.controller-service-canceling').show(); |
| } |
| } |
| }]); |
| |
| // show the progress |
| $('#disable-controller-service-scope-container').hide(); |
| $('#disable-controller-service-progress-container').show(); |
| |
| // get the controller service |
| var controllerServiceId = $('#disable-controller-service-id').text(); |
| var controllerServiceGrid = serviceTable.data('gridInstance'); |
| var controllerServiceData = controllerServiceGrid.getData(); |
| var controllerServiceEntity = controllerServiceData.getItemById(controllerServiceId); |
| var controllerService = controllerServiceEntity.component; |
| |
| // whether or not to continue polling |
| var continuePolling = function () { |
| return canceled === false; |
| }; |
| |
| // sets the close button on the dialog |
| var setCloseButton = function () { |
| $('#disable-controller-service-dialog div.controller-service-canceling').hide(); |
| disableDialog.modal('setButtonModel', [{ |
| buttonText: 'Close', |
| color: { |
| base: '#728E9B', |
| hover: '#004849', |
| text: '#ffffff' |
| }, |
| handler: { |
| click: closeModal |
| } |
| }]); |
| }; |
| |
| // ensure we have access to all referencing components before attempting the sequence |
| if (hasUnauthorizedReferencingComponent(controllerServiceEntity)) { |
| setCloseButton(); |
| |
| nfDialog.showOkDialog({ |
| headerText: 'Controller Service', |
| dialogContent: controllerServiceEntity.permissions.canRead === false |
| // Unknown references. |
| ? 'Unable to disable due to a lack of read permission to see referencing components.' |
| // Unauthorized references. |
| : 'Unable to disable due to unauthorized referencing components.' |
| }); |
| return; |
| } |
| |
| $('#disable-progress-label').text('Steps to disable ' + nfCommon.getComponentName(controllerServiceEntity)); |
| var disableReferencingSchedulable = $('#disable-referencing-schedulable').addClass('ajax-loading'); |
| |
| $.Deferred(function (deferred) { |
| // stop all referencing schedulable components |
| var stopped = updateReferencingSchedulableComponents(serviceTable, controllerServiceEntity, false, continuePolling); |
| |
| // once everything has stopped |
| stopped.done(function () { |
| disableReferencingSchedulable.removeClass('ajax-loading').addClass('ajax-complete'); |
| var disableReferencingServices = $('#disable-referencing-services').addClass('ajax-loading'); |
| |
| // disable all referencing services |
| var disabled = updateReferencingServices(serviceTable, controllerServiceEntity, false, continuePolling); |
| |
| // everything is disabled |
| disabled.done(function () { |
| disableReferencingServices.removeClass('ajax-loading').addClass('ajax-complete'); |
| var disableControllerService = $('#disable-controller-service').addClass('ajax-loading'); |
| |
| // disable this service |
| setEnabled(serviceTable, controllerServiceEntity, false, continuePolling).done(function () { |
| deferred.resolve(); |
| disableControllerService.removeClass('ajax-loading').addClass('ajax-complete'); |
| }).fail(function () { |
| deferred.reject(); |
| disableControllerService.removeClass('ajax-loading').addClass('ajax-error'); |
| }); |
| }).fail(function () { |
| deferred.reject(); |
| disableReferencingServices.removeClass('ajax-loading').addClass('ajax-error'); |
| }); |
| }).fail(function () { |
| deferred.reject(); |
| disableReferencingSchedulable.removeClass('ajax-loading').addClass('ajax-error'); |
| }); |
| }).always(function () { |
| if (controllerServiceEntity.permissions.canRead === true) { |
| reloadControllerServiceAndReferencingComponents(serviceTable, controllerService); |
| } |
| setCloseButton(); |
| |
| // inform the user if the action was canceled |
| if (canceled === true && $('#nf-ok-dialog').not(':visible')) { |
| nfDialog.showOkDialog({ |
| headerText: 'Controller Service', |
| dialogContent: 'The request to disable has been canceled. Parts of this request may have already completed. Please verify the state of this service and all referencing components.' |
| }); |
| } |
| }); |
| }; |
| |
| /** |
| * Determines if any of the specified referencing components are not authorized to enable/disable. |
| * |
| * @param {object} ControllerServiceEntity having referencingComponents referencing components |
| * @returns {boolean} |
| */ |
| var hasUnauthorizedReferencingComponent = function (controllerServiceEntity) { |
| |
| if (controllerServiceEntity.permissions.canRead === false |
| || (controllerServiceEntity.permissions.canWrite === false && controllerServiceEntity.operatePermissions.canWrite === false)) { |
| return true; |
| } |
| |
| var hasUnauthorized = false; |
| var referencingComponents = controllerServiceEntity.component.referencingComponents; |
| $.each(referencingComponents, function (_, referencingComponentEntity) { |
| if (hasUnauthorizedReferencingComponent(referencingComponentEntity)) { |
| hasUnauthorized = true; |
| return false; |
| } |
| }); |
| |
| return hasUnauthorized; |
| }; |
| |
| /** |
| * Handles the enable action of the enable controller service dialog. |
| * |
| * @param {jQuery} serviceTable |
| */ |
| var enableHandler = function (serviceTable) { |
| var enableDialog = $('#enable-controller-service-dialog'); |
| var canceled = false; |
| |
| // get the controller service |
| var controllerServiceId = $('#enable-controller-service-id').text(); |
| var controllerServiceGrid = serviceTable.data('gridInstance'); |
| var controllerServiceData = controllerServiceGrid.getData(); |
| var controllerServiceEntity = controllerServiceData.getItemById(controllerServiceId); |
| var controllerService = controllerServiceEntity.component; |
| |
| // determine if we want to also activate referencing components |
| var scope = $('#enable-controller-service-scope').combo('getSelectedOption').value; |
| |
| // update visibility |
| if (scope === config.serviceOnly) { |
| $('#enable-controller-service-progress li.referencing-component').hide(); |
| } |
| |
| // only provide a cancel option |
| enableDialog.modal('setButtonModel', [{ |
| buttonText: 'Cancel', |
| color: { |
| base: '#E3E8EB', |
| hover: '#C7D2D7', |
| text: '#004849' |
| }, |
| handler: { |
| click: function () { |
| canceled = true; |
| enableDialog.modal('setButtonModel', []); |
| $('#enable-controller-service-dialog div.controller-service-canceling').show(); |
| } |
| } |
| }]); |
| |
| // show the progress |
| $('#enable-controller-service-scope-container').hide(); |
| $('#enable-controller-service-progress-container').show(); |
| |
| |
| // whether or not to continue polling |
| var continuePolling = function () { |
| return canceled === false; |
| }; |
| |
| // sets the button to close |
| var setCloseButton = function () { |
| $('#enable-controller-service-dialog div.controller-service-canceling').hide(); |
| enableDialog.modal('setButtonModel', [{ |
| buttonText: 'Close', |
| color: { |
| base: '#728E9B', |
| hover: '#004849', |
| text: '#ffffff' |
| }, |
| handler: { |
| click: closeModal |
| } |
| }]); |
| }; |
| |
| // ensure appropriate access |
| if (scope === config.serviceAndReferencingComponents && hasUnauthorizedReferencingComponent(controllerServiceEntity)) { |
| setCloseButton(); |
| |
| nfDialog.showOkDialog({ |
| headerText: 'Controller Service', |
| dialogContent: controllerServiceEntity.permissions.canRead === false |
| // Unknown references. |
| ? 'Unable to enable due to a lack of read permission to see referencing components.' |
| // Unauthorized references. |
| : 'Unable to enable due to unauthorized referencing components.' |
| }); |
| return; |
| } |
| |
| $('#enable-progress-label').text('Steps to enable ' + nfCommon.getComponentName(controllerServiceEntity)); |
| var enableControllerService = $('#enable-controller-service').addClass('ajax-loading'); |
| |
| $.Deferred(function (deferred) { |
| // enable this controller service |
| var enable = setEnabled(serviceTable, controllerServiceEntity, true, continuePolling); |
| |
| if (scope === config.serviceAndReferencingComponents) { |
| // once the service is enabled, activate all referencing components |
| enable.done(function () { |
| enableControllerService.removeClass('ajax-loading').addClass('ajax-complete'); |
| var enableReferencingServices = $('#enable-referencing-services').addClass('ajax-loading'); |
| |
| // enable the referencing services |
| var servicesEnabled = updateReferencingServices(serviceTable, controllerServiceEntity, true, continuePolling); |
| |
| // once all the referencing services are enbled |
| servicesEnabled.done(function () { |
| enableReferencingServices.removeClass('ajax-loading').addClass('ajax-complete'); |
| var enableReferencingSchedulable = $('#enable-referencing-schedulable').addClass('ajax-loading'); |
| |
| // start all referencing schedulable components |
| updateReferencingSchedulableComponents(serviceTable, controllerServiceEntity, true, continuePolling).done(function () { |
| deferred.resolve(); |
| enableReferencingSchedulable.removeClass('ajax-loading').addClass('ajax-complete'); |
| }).fail(function () { |
| deferred.reject(); |
| enableReferencingSchedulable.removeClass('ajax-loading').addClass('ajax-error'); |
| }); |
| }).fail(function () { |
| deferred.reject(); |
| enableReferencingServices.removeClass('ajax-loading').addClass('ajax-error'); |
| }); |
| }).fail(function () { |
| deferred.reject(); |
| enableControllerService.removeClass('ajax-loading').addClass('ajax-error'); |
| }); |
| } else { |
| enable.done(function () { |
| deferred.resolve(); |
| enableControllerService.removeClass('ajax-loading').addClass('ajax-complete'); |
| }).fail(function () { |
| deferred.reject(); |
| enableControllerService.removeClass('ajax-loading').addClass('ajax-error'); |
| }); |
| } |
| }).always(function () { |
| if (controllerServiceEntity.permissions.canRead === true) { |
| reloadControllerServiceAndReferencingComponents(serviceTable, controllerService); |
| } |
| setCloseButton(); |
| |
| // inform the user if the action was canceled |
| if (canceled === true && $('#nf-ok-dialog').not(':visible')) { |
| nfDialog.showOkDialog({ |
| headerText: 'Controller Service', |
| dialogContent: 'The request to enable has been canceled. Parts of this request may have already completed. Please verify the state of this service and all referencing components.' |
| }); |
| } |
| }); |
| }; |
| |
| /** |
| * Gets a property descriptor for the controller service currently being configured. |
| * |
| * @param {type} propertyName |
| */ |
| var getControllerServicePropertyDescriptor = function (propertyName) { |
| var controllerServiceEntity = $('#controller-service-configuration').data('controllerServiceDetails'); |
| return $.ajax({ |
| type: 'GET', |
| url: controllerServiceEntity.uri + '/descriptors', |
| data: { |
| propertyName: propertyName |
| }, |
| dataType: 'json' |
| }).fail(nfErrorHandler.handleAjaxError); |
| }; |
| |
| /** |
| * Gets the parameters for the specified property descriptor and group. |
| * |
| * @param propertyDescriptor The property descriptor in question |
| * @param groupId The group in question |
| * @returns {deferred} |
| */ |
| var getParameters = function (propertyDescriptor, groupId) { |
| return $.Deferred(function (deferred) { |
| if (nfCommon.isDefinedAndNotNull(groupId)) { |
| var parameterContext; |
| |
| // attempt to identify the parameter context id, conditional based on whether |
| // the user is configuring the current process group |
| if (groupId === nfCanvasUtils.getGroupId()) { |
| parameterContext = nfCanvasUtils.getParameterContext(); |
| } else { |
| var parentProcessGroup = nfCanvasUtils.getComponentByType('ProcessGroup').get(groupId); |
| parameterContext = parentProcessGroup.parameterContext; |
| } |
| |
| if (nfCommon.isDefinedAndNotNull(parameterContext)) { |
| $.ajax({ |
| type: 'GET', |
| url: '../nifi-api/parameter-contexts/' + encodeURIComponent(parameterContext.id), |
| dataType: 'json' |
| }).done(function (response) { |
| var sensitive = nfCommon.isSensitiveProperty(propertyDescriptor); |
| |
| deferred.resolve(response.component.parameters.map(function (parameterEntity) { |
| return parameterEntity.parameter; |
| }).filter(function (parameter) { |
| return parameter.sensitive === sensitive; |
| })); |
| }).fail(function () { |
| deferred.resolve([]); |
| }); |
| } else { |
| deferred.resolve([]); |
| } |
| } else { |
| deferred.resolve([]); |
| } |
| }).promise(); |
| }; |
| |
| /** |
| * Goes to a service configuration from the property table. |
| * |
| * @param {jQuery} serviceTable |
| */ |
| var goToServiceFromProperty = function (serviceTable) { |
| return $.Deferred(function (deferred) { |
| // close all fields currently being edited |
| $('#controller-service-properties').propertytable('saveRow'); |
| |
| // determine if changes have been made |
| if (isSaveRequired()) { |
| // see if those changes should be saved |
| nfDialog.showYesNoDialog({ |
| headerText: 'Save', |
| dialogContent: 'Save changes before going to this Controller Service?', |
| noHandler: function () { |
| deferred.resolve(); |
| }, |
| yesHandler: function () { |
| var controllerServiceEntity = $('#controller-service-configuration').data('controllerServiceDetails'); |
| saveControllerService(serviceTable, controllerServiceEntity).done(function () { |
| deferred.resolve(); |
| }).fail(function () { |
| deferred.reject(); |
| }); |
| } |
| }); |
| } else { |
| deferred.resolve(); |
| } |
| }).promise(); |
| }; |
| |
| var getParameterContext = function (groupId) { |
| if (_.isNil(groupId)) { |
| return null; |
| } |
| |
| var parameterContext; |
| |
| // attempt to identify the parameter context, conditional based on whether |
| // the user is configuring the current process group |
| if (groupId === nfCanvasUtils.getGroupId()) { |
| parameterContext = nfCanvasUtils.getParameterContext(); |
| } else { |
| var parentProcessGroup = nfCanvasUtils.getComponentByType('ProcessGroup').get(groupId); |
| parameterContext = parentProcessGroup.parameterContext; |
| } |
| |
| return parameterContext; |
| }; |
| |
| var saveControllerService = function (serviceTable, controllerServiceEntity) { |
| // marshal the settings and properties and update the controller service |
| var updatedControllerService = marshalDetails(); |
| |
| // ensure details are valid as far as we can tell |
| if (validateDetails(updatedControllerService)) { |
| updatedControllerService['revision'] = nfClient.getRevision(controllerServiceEntity); |
| |
| var previouslyReferencedServiceIds = []; |
| $.each(identifyReferencedServiceDescriptors(controllerServiceEntity.component), function (_, descriptor) { |
| var modifyingService = !nfCommon.isUndefined(updatedControllerService.component.properties) && !nfCommon.isUndefined(updatedControllerService.component.properties[descriptor.name]); |
| var isCurrentlyConfigured = nfCommon.isDefinedAndNotNull(controllerServiceEntity.component.properties[descriptor.name]); |
| |
| // if we are attempting to update a controller service reference |
| if (modifyingService && isCurrentlyConfigured) { |
| |
| // record the current value if set |
| previouslyReferencedServiceIds.push(controllerServiceEntity.component.properties[descriptor.name]); |
| } |
| }); |
| |
| // update the selected component |
| return $.ajax({ |
| type: 'PUT', |
| data: JSON.stringify(updatedControllerService), |
| url: controllerServiceEntity.uri, |
| dataType: 'json', |
| contentType: 'application/json' |
| }).done(function (response) { |
| // reload the controller service |
| renderControllerService(serviceTable, response); |
| |
| // reload all previously referenced controller services |
| $.each(previouslyReferencedServiceIds, function (_, oldServiceReferenceId) { |
| reloadControllerService(serviceTable, oldServiceReferenceId); |
| }); |
| }).fail(nfErrorHandler.handleConfigurationUpdateAjaxError); |
| } else { |
| return $.Deferred(function (deferred) { |
| deferred.reject(); |
| }).promise(); |
| } |
| }; |
| |
| /** |
| * Identifies the descriptors that identify controller services. |
| * |
| * @param {object} component |
| */ |
| var identifyReferencedServiceDescriptors = function (component) { |
| var referencedServiceDescriptors = []; |
| |
| $.each(component.descriptors, function (_, descriptor) { |
| if (nfCommon.isDefinedAndNotNull(descriptor.identifiesControllerService)) { |
| referencedServiceDescriptors.push(descriptor); |
| } |
| }); |
| |
| return referencedServiceDescriptors; |
| }; |
| |
| /** |
| * Identifies descriptors that reference controller services. |
| * |
| * @param {object} component |
| */ |
| var getReferencedServices = function (component) { |
| var referencedServices = []; |
| |
| $.each(identifyReferencedServiceDescriptors(component), function (_, descriptor) { |
| var referencedServiceId = component.properties[descriptor.name]; |
| |
| // ensure the property is configured |
| if (nfCommon.isDefinedAndNotNull(referencedServiceId) && $.trim(referencedServiceId).length > 0) { |
| referencedServices.push(referencedServiceId); |
| } |
| }); |
| |
| return referencedServices; |
| }; |
| |
| /** |
| * Track the current table |
| */ |
| var currentTable; |
| |
| var nfControllerService = { |
| /** |
| * Initializes the controller service configuration dialog. |
| */ |
| init: function (nfControllerServicesRef, nfReportingTaskRef) { |
| nfControllerServices = nfControllerServicesRef; |
| nfReportingTask = nfReportingTaskRef; |
| |
| // initialize the configuration dialog tabs |
| $('#controller-service-configuration-tabs').tabbs({ |
| tabStyle: 'tab', |
| selectedTabStyle: 'selected-tab', |
| scrollableTabContentStyle: 'scrollable', |
| tabs: [{ |
| name: 'Settings', |
| tabContentId: 'controller-service-standard-settings-tab-content' |
| }, { |
| name: 'Properties', |
| tabContentId: 'controller-service-properties-tab-content' |
| }, { |
| name: 'Comments', |
| tabContentId: 'controller-service-comments-tab-content' |
| }], |
| select: function () { |
| // remove all property detail dialogs |
| nfUniversalCapture.removeAllPropertyDetailDialogs(); |
| |
| // update the property table size in case this is the first time its rendered |
| if ($(this).text() === 'Properties') { |
| $('#controller-service-properties').propertytable('resetTableSize'); |
| } |
| |
| // close all fields currently being edited |
| $('#controller-service-properties').propertytable('saveRow'); |
| |
| // show the border around the processor relationships if necessary |
| var referenceContainer = $('#controller-service-referencing-components'); |
| updateReferencingComponentsBorder(referenceContainer); |
| } |
| }); |
| |
| // initialize the conroller service configuration dialog |
| $('#controller-service-configuration').modal({ |
| headerText: 'Configure Controller Service', |
| scrollableContentStyle: 'scrollable', |
| handler: { |
| close: function () { |
| // empty the referencing components list |
| var referencingComponents = $('#controller-service-referencing-components'); |
| nfCommon.cleanUpTooltips(referencingComponents, 'div.referencing-component-state'); |
| nfCommon.cleanUpTooltips(referencingComponents, 'div.referencing-component-bulletins'); |
| referencingComponents.css('border-width', '0').empty(); |
| |
| // cancel any active edits |
| $('#controller-service-properties').propertytable('cancelEdit'); |
| |
| // clear the tables |
| $('#controller-service-properties').propertytable('clear'); |
| |
| // clear the comments |
| nfCommon.clearField('read-only-controller-service-comments'); |
| |
| // clear the compatible apis |
| $('#controller-service-compatible-apis').empty(); |
| |
| // removed the cached controller service details |
| $('#controller-service-configuration').removeData('controllerServiceDetails'); |
| }, |
| open: function () { |
| nfCommon.toggleScrollable($('#' + this.find('.tab-container').attr('id') + '-content').get(0)); |
| } |
| } |
| }); |
| |
| // initialize the disable service dialog |
| $('#disable-controller-service-dialog').modal({ |
| headerText: 'Disable Controller Service', |
| scrollableContentStyle: 'scrollable', |
| handler: { |
| close: function () { |
| var disableDialog = $(this); |
| |
| // reset visibility |
| $('#disable-controller-service-scope-container').show(); |
| $('#disable-controller-service-progress-container').hide(); |
| |
| // clear the dialog |
| $('#disable-controller-service-id').text(''); |
| $('#disable-controller-service-name').text(''); |
| |
| // bulletins |
| $('#disable-controller-service-bulletins').removeClass('has-bulletins').removeData('bulletins').hide(); |
| nfCommon.cleanUpTooltips($('#disable-controller-service-service-container'), '#disable-controller-service-bulletins'); |
| |
| // reset progress |
| $('div.disable-referencing-components').removeClass('ajax-loading ajax-complete ajax-error'); |
| |
| // referencing components |
| var referencingComponents = $('#disable-controller-service-referencing-components'); |
| nfCommon.cleanUpTooltips(referencingComponents, 'div.referencing-component-state'); |
| nfCommon.cleanUpTooltips(referencingComponents, 'div.referencing-component-bulletins'); |
| referencingComponents.css('border-width', '0').empty(); |
| } |
| } |
| }); |
| |
| // initialize the enable scope combo |
| $('#enable-controller-service-scope').combo({ |
| options: [{ |
| text: 'Service only', |
| value: config.serviceOnly, |
| description: 'Enable only this controller service' |
| }, { |
| text: 'Service and referencing components', |
| value: config.serviceAndReferencingComponents, |
| description: 'Enable this controller service and enable/start all referencing components' |
| }] |
| }); |
| |
| // initialize the enable service dialog |
| $('#enable-controller-service-dialog').modal({ |
| headerText: 'Enable Controller Service', |
| scrollableContentStyle: 'scrollable', |
| handler: { |
| close: function () { |
| var enableDialog = $(this); |
| |
| // reset visibility |
| $('#enable-controller-service-scope-container').show(); |
| $('#enable-controller-service-progress-container').hide(); |
| $('#enable-controller-service-progress li.referencing-component').show(); |
| |
| // clear the dialog |
| $('#enable-controller-service-id').text(''); |
| $('#enable-controller-service-name').text(''); |
| |
| // bulletins |
| $('#enable-controller-service-bulletins').removeClass('has-bulletins').removeData('bulletins').hide(); |
| nfCommon.cleanUpTooltips($('#enable-controller-service-service-container'), '#enable-controller-service-bulletins'); |
| |
| // reset progress |
| $('div.enable-referencing-components').removeClass('ajax-loading ajax-complete ajax-error'); |
| |
| // referencing components |
| var referencingComponents = $('#enable-controller-service-referencing-components'); |
| nfCommon.cleanUpTooltips(referencingComponents, 'div.referencing-component-state'); |
| nfCommon.cleanUpTooltips(referencingComponents, 'div.referencing-component-bulletins'); |
| referencingComponents.css('border-width', '0').empty(); |
| } |
| } |
| }); |
| }, |
| |
| /** |
| * Shows the configuration dialog for the specified controller service. |
| * |
| * @argument {jQuery} serviceTable The controller service table |
| * @argument {object} controllerServiceEntity The controller service |
| */ |
| showConfiguration: function (serviceTable, controllerServiceEntity) { |
| if (nfCommon.isUndefined(currentTable)) { |
| currentTable = serviceTable; |
| } |
| var controllerServiceDialog = $('#controller-service-configuration'); |
| |
| controllerServiceDialog.find('.dialog-header .dialog-header-text').text('Configure Controller Service'); |
| if (controllerServiceDialog.data('mode') !== config.edit || currentTable !== serviceTable) { |
| // update the visibility |
| $('#controller-service-configuration .controller-service-read-only').hide(); |
| $('#controller-service-configuration .controller-service-editable').show(); |
| |
| // conditionally get the parameter deferred function |
| var getParameterDeferred = null; |
| if (nfCommon.isDefinedAndNotNull(controllerServiceEntity.parentGroupId)) { |
| getParameterDeferred = getParameters; |
| } |
| |
| // initialize the property table |
| $('#controller-service-properties').propertytable('destroy').propertytable({ |
| readOnly: false, |
| supportsGoTo: true, |
| dialogContainer: '#new-controller-service-property-container', |
| descriptorDeferred: getControllerServicePropertyDescriptor, |
| parameterDeferred: getParameterDeferred, |
| controllerServiceCreatedDeferred: function (response) { |
| var controllerServicesUri; |
| |
| // calculate the correct uri |
| var createdControllerService = response.component; |
| if (nfCommon.isDefinedAndNotNull(createdControllerService.parentGroupId)) { |
| controllerServicesUri = config.urls.api + '/flow/process-groups/' + encodeURIComponent(createdControllerService.parentGroupId) + '/controller-services'; |
| } else { |
| controllerServicesUri = config.urls.api + '/flow/controller/controller-services'; |
| } |
| |
| // load the controller services accordingly |
| return nfControllerServices.loadControllerServices(controllerServicesUri, serviceTable); |
| }, |
| goToServiceDeferred: function () { |
| return goToServiceFromProperty(serviceTable); |
| }, |
| getParameterContext: function (groupId) { |
| return getParameterContext(groupId); |
| } |
| }); |
| |
| // update the mode |
| controllerServiceDialog.data('mode', config.edit); |
| } |
| |
| //track the current table |
| currentTable = serviceTable; |
| |
| // reload the service in case the property descriptors have changed |
| var reloadService = $.ajax({ |
| type: 'GET', |
| url: controllerServiceEntity.uri, |
| dataType: 'json' |
| }); |
| |
| // get the controller service history |
| var loadHistory = $.ajax({ |
| type: 'GET', |
| url: '../nifi-api/flow/history/components/' + encodeURIComponent(controllerServiceEntity.id), |
| dataType: 'json' |
| }); |
| |
| // once everything is loaded, show the dialog |
| $.when(reloadService, loadHistory).done(function (serviceResponse, historyResponse) { |
| // get the updated controller service |
| controllerServiceEntity = serviceResponse[0]; |
| var controllerService = controllerServiceEntity.component; |
| |
| // get the controller service history |
| var controllerServiceHistory = historyResponse[0].componentHistory; |
| |
| // record the controller service details |
| controllerServiceDialog.data('controllerServiceDetails', controllerServiceEntity); |
| |
| // populate the controller service settings |
| nfCommon.populateField('controller-service-id', controllerService['id']); |
| |
| nfCommon.populateField('controller-service-type', nfCommon.formatType(controllerService)); |
| $('#controller-service-configuration').modal('setSubtitle', nfCommon.formatType(controllerService)); |
| |
| nfCommon.populateField('controller-service-bundle', nfCommon.formatBundle(controllerService['bundle'])); |
| $('#controller-service-name').val(controllerService['name']); |
| $('#controller-service-comments').val(controllerService['comments']); |
| |
| // set the implemented apis |
| if (!nfCommon.isEmpty(controllerService['controllerServiceApis'])) { |
| var formattedControllerServiceApis = nfCommon.getFormattedServiceApis(controllerService['controllerServiceApis']); |
| var serviceTips = nfCommon.formatUnorderedList(formattedControllerServiceApis); |
| $('#controller-service-compatible-apis').append(serviceTips); |
| } else { |
| $('#controller-service-compatible-apis').append('<span class="unset">None</span>'); |
| } |
| |
| // get the reference container |
| var referenceContainer = $('#controller-service-referencing-components'); |
| |
| // load the controller referencing components list |
| createReferencingComponents(serviceTable, referenceContainer, controllerServiceEntity); |
| |
| var buttons = [{ |
| buttonText: 'Apply', |
| color: { |
| base: '#728E9B', |
| hover: '#004849', |
| text: '#ffffff' |
| }, |
| handler: { |
| click: function () { |
| // close all fields currently being edited |
| $('#controller-service-properties').propertytable('saveRow'); |
| |
| // save the controller service |
| saveControllerService(serviceTable, controllerServiceEntity).done(function (response) { |
| reloadControllerServiceReferences(serviceTable, response.component); |
| |
| // close the details panel |
| controllerServiceDialog.modal('hide'); |
| }); |
| } |
| } |
| }, { |
| buttonText: 'Cancel', |
| color: { |
| base: '#E3E8EB', |
| hover: '#C7D2D7', |
| text: '#004849' |
| }, |
| handler: { |
| click: function () { |
| controllerServiceDialog.modal('hide'); |
| } |
| } |
| }]; |
| |
| // determine if we should show the advanced button |
| if (nfCommon.isDefinedAndNotNull(controllerService.customUiUrl) && controllerService.customUiUrl !== '') { |
| buttons.push({ |
| buttonText: 'Advanced', |
| clazz: 'fa fa-cog button-icon', |
| color: { |
| base: '#E3E8EB', |
| hover: '#C7D2D7', |
| text: '#004849' |
| }, |
| handler: { |
| click: function () { |
| var openCustomUi = function () { |
| // reset state and close the dialog manually to avoid hiding the faded background |
| controllerServiceDialog.modal('hide'); |
| |
| // close the settings dialog since the custom ui is also opened in the shell |
| $('#shell-close-button').click(); |
| |
| // show the custom ui |
| nfCustomUi.showCustomUi(controllerServiceEntity, controllerService.customUiUrl, true).done(function () { |
| // once the custom ui is closed, reload the controller service |
| reloadControllerServiceAndReferencingComponents(serviceTable, controllerService); |
| |
| // show the settings |
| nfSettings.showSettings(); |
| }); |
| }; |
| |
| // close all fields currently being edited |
| $('#controller-service-properties').propertytable('saveRow'); |
| |
| // determine if changes have been made |
| if (isSaveRequired()) { |
| // see if those changes should be saved |
| nfDialog.showYesNoDialog({ |
| headerText: 'Save', |
| dialogContent: 'Save changes before opening the advanced configuration?', |
| noHandler: openCustomUi, |
| yesHandler: function () { |
| saveControllerService(serviceTable, controllerServiceEntity).done(function () { |
| // open the custom ui |
| openCustomUi(); |
| }); |
| } |
| }); |
| } else { |
| // if there were no changes, simply open the custom ui |
| openCustomUi(); |
| } |
| } |
| } |
| }); |
| } |
| |
| // set the button model |
| controllerServiceDialog.modal('setButtonModel', buttons); |
| |
| // load the property table |
| $('#controller-service-properties') |
| .propertytable('setGroupId', controllerService.parentGroupId) |
| .propertytable('loadProperties', controllerService.properties, controllerService.descriptors, controllerServiceHistory.propertyHistory); |
| |
| // show the details |
| controllerServiceDialog.modal('show'); |
| |
| // show the border if necessary |
| updateReferencingComponentsBorder(referenceContainer); |
| |
| $('#controller-service-properties').propertytable('resetTableSize'); |
| }).fail(nfErrorHandler.handleAjaxError); |
| }, |
| |
| /** |
| * Shows the controller service details in a read only dialog. |
| * |
| * @param {jQuery} serviceTable |
| * @param {object} controllerServiceEntity |
| */ |
| showDetails: function (serviceTable, controllerServiceEntity) { |
| var controllerServiceDialog = $('#controller-service-configuration'); |
| |
| controllerServiceDialog.find('.dialog-header .dialog-header-text').text('Controller Service Details'); |
| if (controllerServiceDialog.data('mode') !== config.readOnly) { |
| // update the visibility |
| $('#controller-service-configuration .controller-service-read-only').show(); |
| $('#controller-service-configuration .controller-service-editable').hide(); |
| |
| // initialize the property table |
| $('#controller-service-properties').propertytable('destroy').propertytable({ |
| supportsGoTo: true, |
| readOnly: true, |
| getParameterContext: function (groupId) { |
| return getParameterContext(groupId); |
| } |
| }); |
| |
| // update the mode |
| controllerServiceDialog.data('mode', config.readOnly); |
| } |
| |
| // reload the service in case the property descriptors have changed |
| var reloadService = $.ajax({ |
| type: 'GET', |
| url: controllerServiceEntity.uri, |
| dataType: 'json' |
| }); |
| |
| // get the controller service history |
| var loadHistory = $.ajax({ |
| type: 'GET', |
| url: '../nifi-api/flow/history/components/' + encodeURIComponent(controllerServiceEntity.id), |
| dataType: 'json' |
| }); |
| |
| // once everything is loaded, show the dialog |
| $.when(reloadService, loadHistory).done(function (serviceResponse, historyResponse) { |
| // get the updated controller service |
| controllerServiceEntity = serviceResponse[0]; |
| var controllerService = controllerServiceEntity.component; |
| |
| // get the controller service history |
| var controllerServiceHistory = historyResponse[0].componentHistory; |
| |
| // record the controller service details |
| controllerServiceDialog.data('controllerServiceDetails', controllerServiceEntity); |
| |
| // populate the controller service settings |
| nfCommon.populateField('controller-service-id', controllerService['id']); |
| nfCommon.populateField('controller-service-type', nfCommon.formatType(controllerService)); |
| nfCommon.populateField('controller-service-bundle', nfCommon.formatBundle(controllerService['bundle'])); |
| nfCommon.populateField('read-only-controller-service-name', controllerService['name']); |
| nfCommon.populateField('read-only-controller-service-comments', controllerService['comments']); |
| |
| // set the implemented apis |
| if (!nfCommon.isEmpty(controllerService['controllerServiceApis'])) { |
| var formattedControllerServiceApis = nfCommon.getFormattedServiceApis(controllerService['controllerServiceApis']); |
| var serviceTips = nfCommon.formatUnorderedList(formattedControllerServiceApis); |
| $('#controller-service-compatible-apis').append(serviceTips); |
| } else { |
| $('#controller-service-compatible-apis').append('<span class="unset">None</span>'); |
| } |
| |
| // get the reference container |
| var referenceContainer = $('#controller-service-referencing-components'); |
| |
| // load the controller referencing components list |
| createReferencingComponents(serviceTable, referenceContainer, controllerServiceEntity); |
| |
| var buttons = [{ |
| buttonText: 'Ok', |
| color: { |
| base: '#728E9B', |
| hover: '#004849', |
| text: '#ffffff' |
| }, |
| handler: { |
| click: function () { |
| // hide the dialog |
| controllerServiceDialog.modal('hide'); |
| } |
| } |
| }]; |
| |
| // determine if we should show the advanced button |
| if (nfCommon.isDefinedAndNotNull(nfCustomUi) && nfCommon.isDefinedAndNotNull(controllerService.customUiUrl) && controllerService.customUiUrl !== '') { |
| buttons.push({ |
| buttonText: 'Advanced', |
| clazz: 'fa fa-cog button-icon', |
| color: { |
| base: '#E3E8EB', |
| hover: '#C7D2D7', |
| text: '#004849' |
| }, |
| handler: { |
| click: function () { |
| // reset state and close the dialog manually to avoid hiding the faded background |
| controllerServiceDialog.modal('hide'); |
| |
| // close the settings dialog since the custom ui is also opened in the shell |
| $('#shell-close-button').click(); |
| |
| // show the custom ui |
| nfCustomUi.showCustomUi(controllerServiceEntity, controllerService.customUiUrl, false).done(function () { |
| nfSettings.showSettings(); |
| }); |
| } |
| } |
| }); |
| } |
| |
| // show the dialog |
| controllerServiceDialog.modal('setButtonModel', buttons); |
| |
| // load the property table |
| $('#controller-service-properties') |
| .propertytable('setGroupId', controllerService.parentGroupId) |
| .propertytable('loadProperties', controllerService.properties, controllerService.descriptors, controllerServiceHistory.propertyHistory); |
| |
| // show the details |
| controllerServiceDialog.modal('show'); |
| |
| // show the border if necessary |
| updateReferencingComponentsBorder(referenceContainer); |
| |
| $('#controller-service-properties').propertytable('resetTableSize'); |
| }); |
| }, |
| |
| /** |
| * Enables the specified controller service. |
| * |
| * @param {jQuery} serviceTable |
| * @param {object} controllerServiceEntity |
| */ |
| enable: function (serviceTable, controllerServiceEntity) { |
| showEnableControllerServiceDialog(serviceTable, controllerServiceEntity); |
| }, |
| |
| /** |
| * Disables the specified controller service. |
| * |
| * @param {jQuery} serviceTable |
| * @param {object} controllerServiceEntity |
| */ |
| disable: function (serviceTable, controllerServiceEntity) { |
| showDisableControllerServiceDialog(serviceTable, controllerServiceEntity); |
| }, |
| |
| /** |
| * Reloads the services that the specified comonent references. This is |
| * necessary because the specified component state is reflected in the |
| * referenced service referencing components. |
| * |
| * @param {jQuery} serviceTable |
| * @param {object} component |
| */ |
| reloadReferencedServices: function (serviceTable, component) { |
| $.each(getReferencedServices(component), function (_, referencedServiceId) { |
| reloadControllerService(serviceTable, referencedServiceId); |
| }); |
| }, |
| |
| /** |
| * Prompts the user before attempting to delete the specified controller service. |
| * |
| * @param {jQuery} serviceTable |
| * @param {object} controllerServiceEntity |
| */ |
| promptToDeleteController: function (serviceTable, controllerServiceEntity) { |
| // prompt for deletion |
| nfDialog.showYesNoDialog({ |
| headerText: 'Delete Controller Service', |
| dialogContent: 'Delete controller service \'' + nfCommon.escapeHtml(controllerServiceEntity.component.name) + '\'?', |
| yesHandler: function () { |
| nfControllerService.remove(serviceTable, controllerServiceEntity); |
| } |
| }); |
| }, |
| |
| /** |
| * Deletes the specified controller service. |
| * |
| * @param {jQuery} serviceTable |
| * @param {object} controllerServiceEntity |
| */ |
| remove: function (serviceTable, controllerServiceEntity) { |
| // prompt for removal? |
| |
| var revision = nfClient.getRevision(controllerServiceEntity); |
| $.ajax({ |
| type: 'DELETE', |
| url: controllerServiceEntity.uri + '?' + $.param({ |
| 'version': revision.version, |
| 'clientId': revision.clientId, |
| 'disconnectedNodeAcknowledged': nfStorage.isDisconnectionAcknowledged() |
| }), |
| dataType: 'json' |
| }).done(function (response) { |
| // remove the service |
| var controllerServiceGrid = serviceTable.data('gridInstance'); |
| var controllerServiceData = controllerServiceGrid.getData(); |
| controllerServiceData.deleteItem(controllerServiceEntity.id); |
| |
| // reload the as necessary |
| if (controllerServiceEntity.permissions.canRead) { |
| reloadControllerServiceReferences(serviceTable, controllerServiceEntity.component); |
| } |
| }).fail(nfErrorHandler.handleAjaxError); |
| } |
| }; |
| |
| return nfControllerService; |
| })); |