Repository: incubator-nifi Updated Branches: refs/heads/NIFI-250 573a8aa35 -> c1077baf9
NIFI-250: - Enabling/Disabling controller service and referencing components in the appropriate order. - Continuing to setup Reporting Task management in the UI. Project: http://git-wip-us.apache.org/repos/asf/incubator-nifi/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-nifi/commit/c1077baf Tree: http://git-wip-us.apache.org/repos/asf/incubator-nifi/tree/c1077baf Diff: http://git-wip-us.apache.org/repos/asf/incubator-nifi/diff/c1077baf Branch: refs/heads/NIFI-250 Commit: c1077baf95f8c7e5ffc16ccea190b56af59c3fcc Parents: 573a8aa Author: Matt Gilman <[email protected]> Authored: Fri Feb 20 13:39:11 2015 -0500 Committer: Matt Gilman <[email protected]> Committed: Fri Feb 20 13:39:11 2015 -0500 ---------------------------------------------------------------------- ...ontrollerServiceReferencingComponentDTO.java | 26 +- .../org/apache/nifi/web/NiFiServiceFacade.java | 15 +- .../nifi/web/StandardNiFiServiceFacade.java | 7 + .../apache/nifi/web/api/ControllerResource.java | 12 +- .../nifi/web/api/ControllerServiceResource.java | 23 +- .../org/apache/nifi/web/api/dto/DtoFactory.java | 10 + .../nifi/web/dao/ControllerServiceDAO.java | 9 + .../dao/impl/StandardControllerServiceDAO.java | 19 ++ .../src/main/resources/nifi-web-api-context.xml | 1 + .../js/nf/canvas/nf-controller-service.js | 214 ++++++++---- .../src/main/webapp/js/nf/canvas/nf-settings.js | 328 +++++++++++++++---- 11 files changed, 518 insertions(+), 146 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/c1077baf/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ControllerServiceReferencingComponentDTO.java ---------------------------------------------------------------------- diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ControllerServiceReferencingComponentDTO.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ControllerServiceReferencingComponentDTO.java index 9032f9f..0cebe9c 100644 --- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ControllerServiceReferencingComponentDTO.java +++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ControllerServiceReferencingComponentDTO.java @@ -34,7 +34,9 @@ public class ControllerServiceReferencingComponentDTO { private String referenceType; private Integer activeThreadCount; - private Set<ControllerServiceReferencingComponentDTO> references; + + private Boolean referenceCycle; + private Set<ControllerServiceReferencingComponentDTO> referencingComponents; /** * Group id for this component referencing a controller service. If this @@ -134,12 +136,26 @@ public class ControllerServiceReferencingComponentDTO { * * @return */ - public Set<ControllerServiceReferencingComponentDTO> getReferences() { - return references; + public Set<ControllerServiceReferencingComponentDTO> getReferencingComponents() { + return referencingComponents; } - public void setReferences(Set<ControllerServiceReferencingComponentDTO> references) { - this.references = references; + public void setReferencingComponents(Set<ControllerServiceReferencingComponentDTO> referencingComponents) { + this.referencingComponents = referencingComponents; + } + + /** + * If this referencing component represents a ControllerService, this indicates + * whether it has already been represented in this hierarchy. + * + * @return + */ + public Boolean getReferenceCycle() { + return referenceCycle; + } + + public void setReferenceCycle(Boolean referenceCycle) { + this.referenceCycle = referenceCycle; } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/c1077baf/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java ---------------------------------------------------------------------- diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java index 02b97a0..f80545e 100644 --- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java +++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java @@ -19,8 +19,10 @@ package org.apache.nifi.web; import java.util.Collection; import java.util.Date; import java.util.Set; +import org.apache.nifi.controller.ScheduledState; import org.apache.nifi.controller.repository.claim.ContentDirection; +import org.apache.nifi.controller.service.ControllerServiceState; import org.apache.nifi.web.api.dto.BulletinBoardDTO; import org.apache.nifi.web.api.dto.BulletinQueryDTO; import org.apache.nifi.web.api.dto.ClusterDTO; @@ -984,9 +986,9 @@ public interface NiFiServiceFacade { * @param controllerServiceId * @param scheduledState * @param controllerServiceState the value of state - * @return the org.apache.nifi.web.ConfigurationSnapshot<java.util.Set<org.apache.nifi.web.api.dto.ControllerServiceReferencingComponentDTO>> + * @return The referencing component dtos */ - ConfigurationSnapshot<Set<ControllerServiceReferencingComponentDTO>> updateControllerServiceReferencingComponents(Revision revision, String controllerServiceId, org.apache.nifi.controller.ScheduledState scheduledState, org.apache.nifi.controller.service.ControllerServiceState controllerServiceState); + ConfigurationSnapshot<Set<ControllerServiceReferencingComponentDTO>> updateControllerServiceReferencingComponents(Revision revision, String controllerServiceId, ScheduledState scheduledState, ControllerServiceState controllerServiceState); /** * Updates the specified label. @@ -1014,6 +1016,15 @@ public interface NiFiServiceFacade { void verifyUpdateControllerService(ControllerServiceDTO controllerServiceDTO); /** + * Verifies the referencing components of the specified controller service can be updated. + * + * @param controllerServiceId + * @param scheduledState + * @param controllerServiceState + */ + void verifyUpdateControllerServiceReferencingComponents(String controllerServiceId, ScheduledState scheduledState, ControllerServiceState controllerServiceState); + + /** * Verifies the specified controller service can be removed. * * @param controllerServiceId http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/c1077baf/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java ---------------------------------------------------------------------- diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java index ec288d0..c75e123 100644 --- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java +++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java @@ -154,8 +154,10 @@ import org.apache.nifi.web.util.SnippetUtils; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.nifi.controller.ReportingTaskNode; +import org.apache.nifi.controller.ScheduledState; import org.apache.nifi.controller.service.ControllerServiceNode; import org.apache.nifi.controller.service.ControllerServiceReference; +import org.apache.nifi.controller.service.ControllerServiceState; import org.apache.nifi.web.api.dto.ControllerServiceDTO; import org.apache.nifi.web.api.dto.ControllerServiceReferencingComponentDTO; import org.apache.nifi.web.api.dto.ReportingTaskDTO; @@ -335,6 +337,11 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { } @Override + public void verifyUpdateControllerServiceReferencingComponents(String controllerServiceId, ScheduledState scheduledState, ControllerServiceState controllerServiceState) { + controllerServiceDAO.verifyUpdateReferencingComponents(controllerServiceId, scheduledState, controllerServiceState); + } + + @Override public void verifyDeleteControllerService(String controllerServiceId) { controllerServiceDAO.verifyDelete(controllerServiceId); } http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/c1077baf/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java ---------------------------------------------------------------------- diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java index f8c539d..98f17d5 100644 --- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java +++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java @@ -169,6 +169,16 @@ public class ControllerResource extends ApplicationResource { public ControllerServiceResource getControllerServiceResource() { return resourceContext.getResource(ControllerServiceResource.class); } + + /** + * Locates the Reporting Tasks sub-resource. + * + * @return + */ + @Path("/reporting-tasks") + public ReportingTaskResource getReportingTaskResource() { + return resourceContext.getResource(ReportingTaskResource.class); + } /** * Locates the Group sub-resource. @@ -781,7 +791,7 @@ public class ControllerResource extends ApplicationResource { // create response entity final ReportingTaskTypesEntity entity = new ReportingTaskTypesEntity(); entity.setRevision(revision); - entity.setReportingTaskTypes(serviceFacade.getControllerServiceTypes()); + entity.setReportingTaskTypes(serviceFacade.getReportingTaskTypes()); // generate the response return clusterContext(generateOkResponse(entity)).build(); http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/c1077baf/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java ---------------------------------------------------------------------- diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java index 732dec8..a77e376 100644 --- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java +++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java @@ -403,35 +403,34 @@ public class ControllerServiceResource extends ApplicationResource { @FormParam(VERSION) LongParameter version, @FormParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId, @PathParam("availability") String availability, @PathParam("id") String id, - @FormParam("state") String state) { + @FormParam("state") @DefaultValue(StringUtils.EMPTY) String state) { // parse the state to determine the desired action - ScheduledState scheduledState = null; + + // need to consider controller service state first as it shares a state with + // scheduled state (disabled) which is applicable for referencing services + // but not referencing schedulable components + ControllerServiceState controllerServiceState = null; try { - scheduledState = ScheduledState.valueOf(state); + controllerServiceState = ControllerServiceState.valueOf(state); } catch (final IllegalArgumentException iae) { // ignore } - ControllerServiceState controllerServiceState = null; + ScheduledState scheduledState = null; try { - controllerServiceState = ControllerServiceState.valueOf(state); + scheduledState = ScheduledState.valueOf(state); } catch (final IllegalArgumentException iae) { // ignore } // ensure an action has been specified if (scheduledState == null && controllerServiceState == null) { - throw new IllegalArgumentException("Must specify whether updating the state a valid state. To update referencing Processors " + throw new IllegalArgumentException("Must specify the updated state. To update referencing Processors " + "and Reporting Tasks the state should be RUNNING or STOPPED. To update the referencing Controller Services the " + "state should be ENABLED or DISABLED."); } - // ensure the scheduled state is not disabled - if (scheduledState != null && ScheduledState.DISABLED.equals(scheduledState)) { - throw new IllegalArgumentException("Cannot disable referencing components."); - } - // ensure the controller service state is not ENABLING or DISABLING if (controllerServiceState != null && (ControllerServiceState.ENABLING.equals(controllerServiceState) || ControllerServiceState.DISABLING.equals(controllerServiceState))) { throw new IllegalArgumentException("Cannot set the referencing services to ENABLING or DISABLING"); @@ -448,7 +447,7 @@ public class ControllerServiceResource extends ApplicationResource { // handle expects request (usually from the cluster manager) final String expects = httpServletRequest.getHeader(WebClusterManager.NCM_EXPECTS_HTTP_HEADER); if (expects != null) { -// serviceFacade.verifyUpdateControllerServiceReferences(true); + serviceFacade.verifyUpdateControllerServiceReferencingComponents(id, scheduledState, controllerServiceState); return generateContinueResponse().build(); } http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/c1077baf/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java ---------------------------------------------------------------------- diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java index 47c8161..cb13247 100644 --- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java +++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java @@ -912,6 +912,10 @@ public final class DtoFactory { } public Set<ControllerServiceReferencingComponentDTO> createControllerServiceReferencingComponentsDto(final ControllerServiceReference reference) { + return createControllerServiceReferencingComponentsDto(reference, new HashSet<ControllerServiceNode>()); + } + + private Set<ControllerServiceReferencingComponentDTO> createControllerServiceReferencingComponentsDto(final ControllerServiceReference reference, final Set<ControllerServiceNode> visited) { final Set<ControllerServiceReferencingComponentDTO> referencingComponents = new LinkedHashSet<>(); // get all references @@ -932,6 +936,12 @@ public final class DtoFactory { dto.setState(node.getState().name()); dto.setType(node.getControllerServiceImplementation().getClass().getName()); dto.setReferenceType(ControllerService.class.getSimpleName()); + dto.setReferenceCycle(visited.contains(node)); + + // if we haven't encountered this service before include it's referencing components + if (!dto.getReferenceCycle()) { + dto.setReferencingComponents(createControllerServiceReferencingComponentsDto(node.getReferences(), visited)); + } } else if (component instanceof ReportingTask) { final ReportingTaskNode node = ((ReportingTaskNode) component); dto.setState(node.getScheduledState().name()); http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/c1077baf/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/ControllerServiceDAO.java ---------------------------------------------------------------------- diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/ControllerServiceDAO.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/ControllerServiceDAO.java index f613d9c..c1fba0c 100644 --- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/ControllerServiceDAO.java +++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/ControllerServiceDAO.java @@ -86,6 +86,15 @@ public interface ControllerServiceDAO { void verifyUpdate(ControllerServiceDTO controllerServiceDTO); /** + * Determines whether the referencing component of the specified controller service can be updated. + * + * @param controllerServiceId + * @param scheduledState + * @param controllerServiceState + */ + void verifyUpdateReferencingComponents(String controllerServiceId, ScheduledState scheduledState, ControllerServiceState controllerServiceState); + + /** * Determines whether this controller service can be removed. * * @param controllerServiceId http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/c1077baf/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardControllerServiceDAO.java ---------------------------------------------------------------------- diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardControllerServiceDAO.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardControllerServiceDAO.java index a9a63ad..096058d 100644 --- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardControllerServiceDAO.java +++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardControllerServiceDAO.java @@ -182,6 +182,25 @@ public class StandardControllerServiceDAO extends ComponentDAO implements Contro final ControllerServiceNode controllerService = locateControllerService(controllerServiceDTO.getId()); verifyUpdate(controllerService, controllerServiceDTO); } + + @Override + public void verifyUpdateReferencingComponents(String controllerServiceId, ScheduledState scheduledState, ControllerServiceState controllerServiceState) { + final ControllerServiceNode controllerService = locateControllerService(controllerServiceId); + + if (controllerServiceState != null) { + if (ControllerServiceState.ENABLED.equals(controllerServiceState)) { +// serviceProvider.enableReferencingServices(controllerService); + } else { +// serviceProvider.disableReferencingServices(controllerService); + } + } else if (scheduledState != null) { + if (ScheduledState.RUNNING.equals(scheduledState)) { +// serviceProvider.scheduleReferencingComponents(controllerService); + } else { +// serviceProvider.unscheduleReferencingComponents(controllerService); + } + } + } /** * Verifies the controller service can be updated. http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/c1077baf/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/resources/nifi-web-api-context.xml ---------------------------------------------------------------------- diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/resources/nifi-web-api-context.xml b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/resources/nifi-web-api-context.xml index 134199b..34c56b6 100644 --- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/resources/nifi-web-api-context.xml +++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/resources/nifi-web-api-context.xml @@ -102,6 +102,7 @@ <property name="funnelDAO" ref="funnelDAO"/> <property name="connectionDAO" ref="connectionDAO"/> <property name="controllerServiceDAO" ref="controllerServiceDAO"/> + <property name="reportingTaskDAO" ref="reportingTaskDAO"/> <property name="templateDAO" ref="templateDAO"/> <property name="snippetDAO" ref="snippetDAO"/> <property name="auditService" ref="auditService"/> http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/c1077baf/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-service.js ---------------------------------------------------------------------- diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-service.js b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-service.js index 45d949a..3aeef8a 100644 --- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-service.js +++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-controller-service.js @@ -278,9 +278,8 @@ nf.ControllerService = (function () { }); var serviceState = $('<div class="referencing-component-state"></div>').addClass(referencingComponent.state === 'ENABLED' ? 'enabled' : 'disabled').addClass(referencingComponent.id + '-active-threads'); - var serviceId = $('<span class="referencing-service-id hidden"></span>').text(referencingComponent.id); var serviceType = $('<span class="referencing-component-type"></span>').text(nf.Common.substringAfterLast(referencingComponent.type, '.')); - var serviceItem = $('<li></li>').append(serviceTwist).append(serviceState).append(serviceId).append(serviceLink).append(serviceType).append(referencingServiceReferencesContainer); + var serviceItem = $('<li></li>').append(serviceTwist).append(serviceState).append(serviceLink).append(serviceType).append(referencingServiceReferencesContainer); services.append(serviceItem); } else if (referencingComponent.referenceType === 'ReportingTask') { @@ -323,7 +322,12 @@ nf.ControllerService = (function () { createReferenceBlock('Controller Services', services); }; - // sets whether the specified controller service is enabled + /** + * Sets whether the specified controller service is enabled. + * + * @param {object} controllerService + * @param {boolean} enabled + */ var setEnabled = function (controllerService, enabled) { var revision = nf.Client.getRevision(); return $.ajax({ @@ -344,8 +348,43 @@ nf.ControllerService = (function () { }).fail(nf.Common.handleAjaxError); }; - // updates the referencing components with the specified state - var updateReferencingComponents = function (controllerService, activated) { + /** + * 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 (_, referencingComponent) { + 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 servcies + checkReferencingServices(controllerService.referencingComponents); + return ids; + }; + + /** + * Updates the scheduled state of the processors/reporting tasks referencing + * the specified controller service. + * + * @param {type} controllerService + * @param {type} running + * @returns {unresolved} + */ + var updateReferencingSchedulableComponents = function (controllerService, running) { var revision = nf.Client.getRevision(); // issue the request to update the referencing components @@ -355,7 +394,7 @@ nf.ControllerService = (function () { data: { clientId: revision.clientId, version: revision.version, - activated: activated + state: running ? 'RUNNING' : 'STOPPED' }, dataType: 'json' }).done(function (response) { @@ -366,19 +405,14 @@ nf.ControllerService = (function () { reloadControllerServiceReferences(controllerService); }).fail(nf.Common.handleAjaxError); - // if we are activating, we can stop here - if (activated === true) { + // if we're just starting schedulable components we're done when the + // update is finished + if (running) { return updated; } - // identify all services... this service - var services = d3.set(); - services.add(controllerService.id); - - // and all referencing services - $('span.referencing-service-id').each(function() { - services.add($(this).text()); - }); + // identify all referencing services + var services = getReferencingControllerServiceIds(controllerService); // get the controller service grid var controllerServiceGrid = $('#controller-services-table').data('gridInstance'); @@ -388,7 +422,7 @@ nf.ControllerService = (function () { var polling = []; services.forEach(function(controllerServiceId) { var controllerService = controllerServiceData.getItemById(controllerServiceId); - polling.push(pollControllerServiceStatus(controllerService)); + polling.push(pollStoppedReferencingSchedulableComponents(controllerService)); }); // wait unil the polling of each service finished @@ -401,10 +435,15 @@ nf.ControllerService = (function () { }).promise(); }; - // polls for the status of the specified controller service - var pollControllerServiceStatus = function (controllerService) { - // since we are deactivating, we want to keep polling until - // everything has stopped and there are 0 active threads + /** + * Polls the specified services referencing components to see if the + * specified condition is satisfied. + * + * @param {object} controllerService + * @param {function} condition + */ + var pollReferencingComponents = function (controllerService, condition) { + // we want to keep polling until the condition is met return $.Deferred(function(deferred) { var current = 1; var getTimeout = function () { @@ -417,54 +456,86 @@ nf.ControllerService = (function () { }; // polls for the current status of the referencing components - var pollReferencingComponents = function() { + var poll = function() { $.ajax({ type: 'GET', url: controllerService.uri + '/references', dataType: 'json' }).done(function (response) { - checkDeactivated(response.controllerServiceReferencingComponents); + if (condition(response.controllerServiceReferencingComponents)) { + deferred.resolve(); + } else { + setTimeout(poll(), getTimeout()); + } }).fail(function (xhr, status, error) { deferred.reject(); nf.Common.handleAjaxError(xhr, status, error); }); }; - // checks the referencing components to see if any are still active - var checkDeactivated = function (controllerServiceReferencingComponents) { - var stillRunning = false; - - $.each(controllerServiceReferencingComponents, function(referencingComponent) { - if (referencingComponent.referenceType === 'ControllerService') { - if (referencingComponent.enable === true) { - // update the current values for this component - $(referencingComponent.id + '-state').removeClass('enabled disabled').addClass(referencingComponent.state === 'ENABLED' ? 'enabled' : 'disabled'); - - // mark that something is still running - stillRunning = true; - } - } else { - if (referencingComponent.state === 'RUNNING' || referencingComponent.activeThreadCount > 0) { - // update the current values for this component - $(referencingComponent.id + '-active-threads').text(referencingComponent.activeThreadCount); - $(referencingComponent.id + '-state').removeClass('disabled stopped running').addClass(referencingComponent.state.toLowerCase()); - - // mark that something is still running - stillRunning = true; - } + // poll for the status of the referencing components + poll(); + }).promise(); + }; + + /** + * Continues to poll the specified controller service until all referencing schedulable + * components are stopped (not scheduled and 0 active threads). + * + * @param {object} controllerService + */ + var pollStoppedReferencingSchedulableComponents = function (controllerService) { + // continue to poll the service until all schedulable components have stopped + return pollReferencingComponents(controllerService, function (referencingComponents) { + var stillRunning = false; + + $.each(referencingComponents, function(referencingComponent) { + if (referencingComponent.referenceType === 'Processor' || referencingComponent.referenceType === 'ReportingTask') { + if (referencingComponent.state === 'RUNNING' || referencingComponent.activeThreadCount > 0) { + // update the current values for this component + $(referencingComponent.id + '-active-threads').text(referencingComponent.activeThreadCount); + $(referencingComponent.id + '-state').removeClass('disabled stopped running').addClass(referencingComponent.state.toLowerCase()); + + // mark that something is still running + stillRunning = true; } - }); - - if (stillRunning) { - setTimeout(pollReferencingComponents(), getTimeout()); - } else { - deferred.resolve(); } - }; + }); + + // condition is met once all referencing are not running + return stillRunning === false; + }); + }; + + /** + * Updates the referencing services with the specified state. + * + * @param {type} controllerService + * @param {type} enabled + */ + var updateReferencingServices = function (controllerService, enabled) { + var revision = nf.Client.getRevision(); + + // issue the request to update the referencing components + var updated = $.ajax({ + type: 'PUT', + url: controllerService.uri + '/references', + data: { + clientId: revision.clientId, + version: revision.version, + state: enabled ? 'ENABLED' : 'DISABLED' + }, + dataType: 'json' + }).done(function (response) { + // update the revision + nf.Client.setRevision(response.revision); - // poll for the status of the referencing components - pollReferencingComponents(); - }).promise(); + // update the service + reloadControllerServiceReferences(controllerService); + }).fail(nf.Common.handleAjaxError); + + // need to wait until finished ENALBING or DISABLING? + return updated; }; /** @@ -593,15 +664,21 @@ nf.ControllerService = (function () { var controllerServiceData = controllerServiceGrid.getData(); var controllerService = controllerServiceData.getItemById(controllerServiceId); - // deactivate all referencing components - var deactivated = updateReferencingComponents(controllerService, false); + // stop all referencing schedulable components + var stopped = updateReferencingSchedulableComponents(controllerService, false); - // once all referencing components have been deactivated... - deactivated.done(function() { - // disable this service - setEnabled(controllerService, false).done(function() { - // close the dialog - $('#disable-controller-service-dialog').modal('hide'); + // once everything has stopped + stopped.done(function () { + // disable all referencing services + var disabled = updateReferencingServices(controllerService, false); + + // everything is disabled + disabled.done(function () { + // disalbe this service + setEnabled(controllerService, false).done(function () { + // close the dialog + $('#disable-controller-service-dialog').modal('hide'); + }); }); }); } @@ -663,7 +740,16 @@ nf.ControllerService = (function () { if (scope === config.serviceAndReferencingComponents) { // once the service is enabled, activate all referencing components enabled.done(function() { - updateReferencingComponents(controllerService, true); + // enable the referencing services + var servicesEnabled = updateReferencingServices(controllerService, true); + + // once all the referencing services are enbled + servicesEnabled.done(function () { + // start all referencing schedulable components + updateReferencingSchedulableComponents(controllerService, true).done(function() { + // hide the dialog now? + }); + }); }); } http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/c1077baf/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js ---------------------------------------------------------------------- diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js index 33fd1d0..f4191f7 100644 --- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js +++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-settings.js @@ -32,6 +32,15 @@ nf.Settings = (function () { reportingTasks: '../nifi-api/controller/reporting-tasks' } }; + + var gridOptions = { + forceFitColumns: true, + enableTextSelectionOnCells: true, + enableCellNavigation: true, + enableColumnReorder: false, + autoEdit: false, + multiSelect: false + }; /** * Initializes the general tab. @@ -324,7 +333,7 @@ nf.Settings = (function () { * @param {type} columnDef * @param {type} dataContext */ - var typeFormatter = function (row, cell, value, columnDef, dataContext) { + var expandableTypeFormatter = function (row, cell, value, columnDef, dataContext) { var markup = ''; var indent = 0; @@ -464,17 +473,9 @@ nf.Settings = (function () { // initialize the processor type table var controllerServiceTypesColumns = [ - {id: 'type', name: 'Type', field: 'label', formatter: typeFormatter, sortable: false, resizable: true}, + {id: 'type', name: 'Type', field: 'label', formatter: expandableTypeFormatter, sortable: false, resizable: true}, {id: 'tags', name: 'Tags', field: 'tags', sortable: false, resizable: true} ]; - var controllerServiceTypesOptions = { - forceFitColumns: true, - enableTextSelectionOnCells: true, - enableCellNavigation: true, - enableColumnReorder: false, - autoEdit: false, - multiSelect: false - }; // initialize the dataview var controllerServiceTypesData = new Slick.Data.DataView({ @@ -514,7 +515,7 @@ nf.Settings = (function () { }; // initialize the grid - var controllerServiceTypesGrid = new Slick.Grid('#controller-service-types-table', controllerServiceTypesData, controllerServiceTypesColumns, controllerServiceTypesOptions); + var controllerServiceTypesGrid = new Slick.Grid('#controller-service-types-table', controllerServiceTypesData, controllerServiceTypesColumns, gridOptions); controllerServiceTypesGrid.setSelectionModel(new Slick.RowSelectionModel()); controllerServiceTypesGrid.registerPlugin(new Slick.AutoTooltips()); controllerServiceTypesGrid.setSortColumn('type', true); @@ -671,10 +672,45 @@ nf.Settings = (function () { // clear the tagcloud $('#controller-service-tag-cloud').tagcloud('clearSelectedTags'); } + }).draggable({ + containment: 'parent', + handle: '.dialog-header' }); }; /** + * Formatter for the type column. + * + * @param {type} row + * @param {type} cell + * @param {type} value + * @param {type} columnDef + * @param {type} dataContext + * @returns {String} + */ + var typeFormatter = function (row, cell, value, columnDef, dataContext) { + return nf.Common.substringAfterLast(value, '.'); + }; + + /** + * Formatter for the availability column. + * + * @param {type} row + * @param {type} cell + * @param {type} value + * @param {type} columnDef + * @param {type} dataContext + * @returns {String} + */ + var availabilityFormatter = function (row, cell, value, columnDef, dataContext) { + if (value === config.node) { + return 'Node'; + } else { + return 'Cluster Manager'; + } + }; + + /** * Sorts the specified data using the specified sort details. * * @param {object} sortDetails @@ -708,11 +744,6 @@ nf.Settings = (function () { return markup; }; - // type formatter - var typeFormatter = function (row, cell, value, columnDef, dataContext) { - return nf.Common.substringAfterLast(value, '.'); - }; - // define the column model for the controller services table var controllerServicesColumns = [ {id: 'moreDetails', name: ' ', resizable: false, formatter: moreControllerServiceDetails, sortable: false, width: 50, maxWidth: 50}, @@ -723,14 +754,6 @@ nf.Settings = (function () { // only show availability when clustered if (nf.Canvas.isClustered()) { - var availabilityFormatter = function (row, cell, value, columnDef, dataContext) { - if (value === config.node) { - return 'Node'; - } else { - return 'Cluster Manager'; - } - }; - controllerServicesColumns.push({id: 'availability', field: 'availability', name: 'Availability', formatter: availabilityFormatter, sortable: true, resizeable: true}); } @@ -758,15 +781,6 @@ nf.Settings = (function () { controllerServicesColumns.push({id: 'actions', name: ' ', resizable: false, formatter: controllerServiceActionFormatter, sortable: false, width: 75, maxWidth: 75}); } - var controllerServicesOptions = { - forceFitColumns: true, - enableTextSelectionOnCells: true, - enableCellNavigation: true, - enableColumnReorder: false, - autoEdit: false, - multiSelect: false - }; - // initialize the dataview var controllerServicesData = new Slick.Data.DataView({ inlineFilters: false @@ -780,7 +794,7 @@ nf.Settings = (function () { }, controllerServicesData); // initialize the grid - var controllerServicesGrid = new Slick.Grid('#controller-services-table', controllerServicesData, controllerServicesColumns, controllerServicesOptions); + var controllerServicesGrid = new Slick.Grid('#controller-services-table', controllerServicesData, controllerServicesColumns, gridOptions); controllerServicesGrid.setSelectionModel(new Slick.RowSelectionModel()); controllerServicesGrid.registerPlugin(new Slick.AutoTooltips()); controllerServicesGrid.setSortColumn('name', true); @@ -909,7 +923,7 @@ nf.Settings = (function () { var controllerServicesGrid = controllerServicesElement.data('gridInstance'); var controllerServicesData = controllerServicesGrid.getData(); - // update the processors + // update the controller services controllerServicesData.setItems(services); controllerServicesData.reSort(); controllerServicesGrid.invalidate(); @@ -955,6 +969,32 @@ nf.Settings = (function () { }; /** + * Hides the selected reporting task. + */ + var clearSelectedReportingTask = function () { + $('#reporting-task-type-description').text(''); + $('#reporting-task-type-name').text(''); + $('#reporting-task-availability-combo').combo('setSelectedOption', { + value: config.node + }); + $('#selected-reporting-task-name').text(''); + $('#selected-reporting-task-type').text(''); + $('#reporting-task-description-container').hide(); + }; + + /** + * Clears the selected reporting task type. + */ + var clearReportingTaskSelection = function () { + // clear the selected row + clearSelectedReportingTask(); + + // clear the active cell the it can be reselected when its included + var reportingTaskTypesGrid = $('#reporting-task-types-table').data('gridInstance'); + reportingTaskTypesGrid.resetActiveCell(); + }; + + /** * Performs the filtering. * * @param {object} item The item subject to filtering @@ -980,7 +1020,7 @@ nf.Settings = (function () { // if this row is currently selected and its being filtered if (matches === false && $('#selected-reporting-task-type').text() === item['type']) { -// clearControllerServiceSelection(); + clearReportingTaskSelection(); } // update visibility flag @@ -990,7 +1030,7 @@ nf.Settings = (function () { }; /** - * Adds a new controller service of the specified type. + * Adds a new reporting task of the specified type. * * @param {string} reportingTaskType */ @@ -1020,17 +1060,17 @@ nf.Settings = (function () { nf.Client.setRevision(response.revision); // add the item - var reportingTaskService = response.reportingTask; + var reportingTask = response.reportingTask; var reportingTaskGrid = $('#reporting-tasks-table').data('gridInstance'); var reportingTaskData = reportingTaskGrid.getData(); - reportingTaskData.addItem(reportingTaskService); + reportingTaskData.addItem(reportingTask); // resort reportingTaskData.reSort(); reportingTaskGrid.invalidate(); - // select the new controller service - var row = reportingTaskData.getRowById(reportingTaskService.id); + // select the new reporting task + var row = reportingTaskData.getRowById(reportingTask.id); reportingTaskGrid.setSelectedRows([row]); }); @@ -1058,17 +1098,17 @@ nf.Settings = (function () { } }); - // specify the controller service availability + // specify the reporting task availability if (nf.Canvas.isClustered()) { $('#reporting-task-availability-combo').combo({ options: [{ text: 'Node', value: config.node, - description: 'This controller service will be available on the nodes only.' + description: 'This reporting task will be available on the nodes only.' }, { text: 'Cluster Manager', value: config.ncm, - description: 'This controller service will be available on the cluster manager only.' + description: 'This reporting task will be available on the cluster manager only.' }] }); $('#reporting-task-availability-container').show(); @@ -1092,14 +1132,6 @@ nf.Settings = (function () { {id: 'type', name: 'Type', field: 'label', sortable: false, resizable: true}, {id: 'tags', name: 'Tags', field: 'tags', sortable: false, resizable: true} ]; - var reportingTaskTypesOptions = { - forceFitColumns: true, - enableTextSelectionOnCells: true, - enableCellNavigation: true, - enableColumnReorder: false, - autoEdit: false, - multiSelect: false - }; // initialize the dataview var reportingTaskTypesData = new Slick.Data.DataView({ @@ -1113,7 +1145,7 @@ nf.Settings = (function () { reportingTaskTypesData.setFilter(filterReportingTaskTypes); // initialize the grid - var reportingTaskTypesGrid = new Slick.Grid('#reporting-task-types-table', reportingTaskTypesData, reportingTaskTypesColumns, reportingTaskTypesOptions); + var reportingTaskTypesGrid = new Slick.Grid('#reporting-task-types-table', reportingTaskTypesData, reportingTaskTypesColumns, gridOptions); reportingTaskTypesGrid.setSelectionModel(new Slick.RowSelectionModel()); reportingTaskTypesGrid.registerPlugin(new Slick.AutoTooltips()); reportingTaskTypesGrid.setSortColumn('type', true); @@ -1133,7 +1165,7 @@ nf.Settings = (function () { $('#selected-reporting-task-name').text(reportingTaskType.label); $('#selected-reporting-task-type').text(reportingTaskType.type); - // show the selected controller service + // show the selected reporting task $('#reporting-task-description-container').show(); }); reportingTaskTypesGrid.onDblClick.subscribe(function (e, args) { @@ -1204,9 +1236,9 @@ nf.Settings = (function () { }); }).fail(nf.Common.handleAjaxError); - // initialize the controller service dialog + // initialize the reporting task dialog $('#new-reporting-task-dialog').modal({ - headerText: 'Add Controller Service', + headerText: 'Add Reporting Task', overlayBackground: false, buttons: [{ buttonText: 'Add', @@ -1226,7 +1258,7 @@ nf.Settings = (function () { }], close: function() { // clear the selected row -// clearSelectedControllerService(); + clearSelectedReportingTask(); // unselect any current selection var reportingTaskTypesGrid = $('#reporting-task-types-table').data('gridInstance'); @@ -1239,6 +1271,9 @@ nf.Settings = (function () { // clear the tagcloud $('#reporting-task-tag-cloud').tagcloud('clearSelectedTags'); } + }).draggable({ + containment: 'parent', + handle: '.dialog-header' }); }; @@ -1250,22 +1285,193 @@ nf.Settings = (function () { initNewReportingTaskDialog(); var moreReportingTaskDetails = function (row, cell, value, columnDef, dataContext) { - return '<img src="images/iconDetails.png" title="View Details" class="pointer view-reporting-task" style="margin-top: 5px; float: left;" />'; + var markup = '<img src="images/iconDetails.png" title="View Details" class="pointer view-reporting-task" style="margin-top: 5px; float: left;" /> '; + if (!nf.Common.isEmpty(dataContext.validationErrors)) { + markup += '<img src="images/iconAlert.png" class="has-errors" style="margin-top: 4px; float: left;" /><span class="hidden row-id">' + nf.Common.escapeHtml(dataContext.id) + '</span>'; + } + return markup; }; // define the column model for the reporting tasks table var reportingTasksColumnModel = [ {id: 'moreDetails', field: 'moreDetails', name: ' ', resizable: false, formatter: moreReportingTaskDetails, sortable: true, width: 50, maxWidth: 50}, {id: 'name', field: 'name', name: 'Name', sortable: true, resizable: true}, - {id: 'type', field: 'type', name: 'Type', sortable: true, resizable: true} + {id: 'type', field: 'type', name: 'Type', sortable: true, resizable: true, formatter: typeFormatter}, + {id: 'state', field: 'state', name: 'State', sortable: true, resizeable: true} ]; + + // only show availability when clustered + if (nf.Canvas.isClustered()) { + reportingTasksColumnModel.push({id: 'availability', field: 'availability', name: 'Availability', formatter: availabilityFormatter, sortable: true, resizeable: true}); + } + + // only DFM can edit reporting tasks + if (nf.Common.isDFM()) { + var reportingTaskActionFormatter = function (row, cell, value, columnDef, dataContext) { + var markup = ''; + + if (dataContext.state === 'ENABLED' || dataContext.state === 'ENABLING') { + markup += '<img src="images/iconDisable.png" title="Disable" class="pointer disable-controller-service" style="margin-top: 2px;" /> '; + } else if (dataContext.state === 'DISABLED') { + markup += '<img src="images/iconEdit.png" title="Edit" class="pointer edit-controller-service" style="margin-top: 2px;" /> '; + + // only enable the enable icon if the service has no validation errors + if (nf.Common.isEmpty(dataContext.validationErrors)) { + markup += '<img src="images/iconEnable.png" title="Enable" class="pointer enable-controller-service" style="margin-top: 2px;"/> '; + } + + markup += '<img src="images/iconDelete.png" title="Remove" class="pointer delete-controller-service" style="margin-top: 2px;" /> '; + } + + return markup; + }; + + reportingTasksColumnModel.push({id: 'actions', name: ' ', resizable: false, formatter: reportingTaskActionFormatter, sortable: false, width: 75, maxWidth: 75}); + } + + // initialize the dataview + var reportingTasksData = new Slick.Data.DataView({ + inlineFilters: false + }); + reportingTasksData.setItems([]); + + // initialize the sort + sort({ + columnId: 'name', + sortAsc: true + }, reportingTasksData); + + // initialize the grid + var reportingTasksGrid = new Slick.Grid('#reporting-tasks-table', reportingTasksData, reportingTasksColumnModel, gridOptions); + reportingTasksGrid.setSelectionModel(new Slick.RowSelectionModel()); + reportingTasksGrid.registerPlugin(new Slick.AutoTooltips()); + reportingTasksGrid.setSortColumn('name', true); + reportingTasksGrid.onSort.subscribe(function (e, args) { + sort({ + columnId: args.sortCol.field, + sortAsc: args.sortAsc + }, reportingTasksData); + }); + + // configure a click listener + reportingTasksGrid.onClick.subscribe(function (e, args) { + var target = $(e.target); + + // get the service at this row + var reportingTask = reportingTasksData.getItem(args.row); + + // determine the desired action + if (reportingTasksGrid.getColumns()[args.cell].id === 'actions') { + if (target.hasClass('edit-reporting-task')) { + } else if (target.hasClass('start-reporting-task')) { + } else if (target.hasClass('stop-reporting-task')) { + } else if (target.hasClass('delete-reporting-task')) { + } + } else if (reportingTasksGrid.getColumns()[args.cell].id === 'moreDetails') { + if (target.hasClass('view-reporting-task')) { + + } + } + }); + + // wire up the dataview to the grid + reportingTasksData.onRowCountChanged.subscribe(function (e, args) { + reportingTasksGrid.updateRowCount(); + reportingTasksGrid.render(); + }); + reportingTasksData.onRowsChanged.subscribe(function (e, args) { + reportingTasksGrid.invalidateRows(args.rows); + reportingTasksGrid.render(); + }); + reportingTasksData.syncGridSelection(reportingTasksGrid, true); + + // hold onto an instance of the grid + $('#reporting-tasks-table').data('gridInstance', reportingTasksGrid).on('mouseenter', 'div.slick-cell', function (e) { + var errorIcon = $(this).find('img.has-errors'); + if (errorIcon.length && !errorIcon.data('qtip')) { + var taskId = $(this).find('span.row-id').text(); + + // get the service item + var item = reportingTasksData.getItemById(taskId); + + // format the errors + var tooltip = nf.Common.formatUnorderedList(item.validationErrors); + + // show the tooltip + if (nf.Common.isDefinedAndNotNull(tooltip)) { + errorIcon.qtip($.extend({ + content: tooltip, + position: { + target: 'mouse', + viewport: $(window), + adjust: { + x: 8, + y: 8, + method: 'flipinvert flipinvert' + } + } + }, nf.Common.config.tooltipConfig)); + } + } + }); }; /** * Loads the reporting tasks. */ var loadReportingTasks = function () { + var tasks = []; + + // get the reporting tasks that are running on the nodes + var nodeReportingTasks = $.ajax({ + type: 'GET', + url: config.urls.reportingTasks + '/' + encodeURIComponent(config.node), + dataType: 'json' + }).done(function(response) { + var nodeTasks = response.reportingTasks; + if (nf.Common.isDefinedAndNotNull(nodeTasks)) { + $.each(nodeTasks, function(_, nodeTask) { + tasks.push(nodeTask); + }); + } + }); + // get the reporting tasks that are running on the ncm + var ncmReportingTasks = $.Deferred(function(deferred) { + if (nf.Canvas.isClustered()) { + $.ajax({ + type: 'GET', + url: config.urls.reportingTasks + '/' + encodeURIComponent(config.ncm), + dataType: 'json' + }).done(function(response) { + var ncmTasks = response.reportingTasks; + if (nf.Common.isDefinedAndNotNull(ncmTasks)) { + $.each(ncmTasks, function(_, ncmTask) { + tasks.push(ncmTask); + }); + } + deferred.resolve(); + }).fail(function() { + deferred.reject(); + }); + } else { + deferred.resolve(); + } + }).promise(); + + // add all reporting tasks + return $.when(nodeReportingTasks, ncmReportingTasks).done(function() { + var reportingTasksElement = $('#reporting-tasks-table'); + nf.Common.cleanUpTooltips(reportingTasksElement, 'img.has-errors'); + + var reportingTasksGrid = reportingTasksElement.data('gridInstance'); + var reportingTasksData = reportingTasksGrid.getData(); + + // update the reporting tasks + reportingTasksData.setItems(tasks); + reportingTasksData.reSort(); + reportingTasksGrid.invalidate(); + }); }; return { @@ -1404,9 +1610,7 @@ nf.Settings = (function () { var reportingTasks = loadReportingTasks(); // return a deferred for all parts of the settings - return $.when(settings, controllerServices, reportingTasks).done(function () { - - }).fail(nf.Common.handleAjaxError); + return $.when(settings, controllerServices, reportingTasks).fail(nf.Common.handleAjaxError); } }; }()); \ No newline at end of file
