Repository: nifi Updated Branches: refs/heads/NIFI-108 de264b1c7 -> bbe819811
NIFI-108: - Adding initial listing capabilities. - Passing through the sort column and direction. Project: http://git-wip-us.apache.org/repos/asf/nifi/repo Commit: http://git-wip-us.apache.org/repos/asf/nifi/commit/bbe81981 Tree: http://git-wip-us.apache.org/repos/asf/nifi/tree/bbe81981 Diff: http://git-wip-us.apache.org/repos/asf/nifi/diff/bbe81981 Branch: refs/heads/NIFI-108 Commit: bbe819811752d5710626a19ec813225e67826562 Parents: de264b1 Author: Matt Gilman <[email protected]> Authored: Thu Dec 17 23:04:48 2015 -0500 Committer: Matt Gilman <[email protected]> Committed: Thu Dec 17 23:04:48 2015 -0500 ---------------------------------------------------------------------- .../nifi/web/api/dto/FlowFileSummaryDTO.java | 34 +- .../nifi/controller/FlowFileSummaries.java | 4 +- .../org/apache/nifi/web/NiFiServiceFacade.java | 6 +- .../nifi/web/StandardNiFiServiceFacade.java | 6 +- .../apache/nifi/web/api/ConnectionResource.java | 44 +- .../org/apache/nifi/web/api/dto/DtoFactory.java | 24 +- .../org/apache/nifi/web/dao/ConnectionDAO.java | 6 +- .../web/dao/impl/StandardConnectionDAO.java | 6 +- .../src/main/resources/nifi-web-api-context.xml | 1 + .../nifi-framework/nifi-web/nifi-web-ui/pom.xml | 2 + .../main/resources/filters/canvas.properties | 1 + .../src/main/webapp/WEB-INF/pages/canvas.jsp | 2 + .../canvas/listing-request-status-dialog.jsp | 29 ++ .../WEB-INF/partials/canvas/queue-listing.jsp | 29 ++ .../nifi-web-ui/src/main/webapp/css/canvas.css | 1 + .../nifi-web-ui/src/main/webapp/css/dialog.css | 21 +- .../src/main/webapp/css/queue-listing.css | 86 ++++ .../src/main/webapp/images/iconListQueue.png | Bin 0 -> 1502 bytes .../src/main/webapp/js/nf/canvas/nf-actions.js | 25 +- .../src/main/webapp/js/nf/canvas/nf-canvas.js | 1 + .../main/webapp/js/nf/canvas/nf-context-menu.js | 11 + .../webapp/js/nf/canvas/nf-queue-listing.js | 435 +++++++++++++++++++ 22 files changed, 730 insertions(+), 44 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/nifi/blob/bbe81981/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/FlowFileSummaryDTO.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/FlowFileSummaryDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/FlowFileSummaryDTO.java index 06b2776..e787e41 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/FlowFileSummaryDTO.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/FlowFileSummaryDTO.java @@ -17,10 +17,6 @@ package org.apache.nifi.web.api.dto; import com.wordnik.swagger.annotations.ApiModelProperty; -import org.apache.nifi.web.api.dto.util.TimestampAdapter; - -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import java.util.Date; public class FlowFileSummaryDTO { @@ -30,8 +26,8 @@ public class FlowFileSummaryDTO { private String filename; private Integer position; private Long size; - private Date lastQueuedTime; - private Date linageStartDate; + private Long queuedDuration; + private Long lineageDuration; private Boolean isPenalized; private String clusterNodeId; @@ -107,33 +103,31 @@ public class FlowFileSummaryDTO { } /** - * @return when the FlowFile was last added to the queue + * @return how long this FlowFile has been enqueued */ - @XmlJavaTypeAdapter(TimestampAdapter.class) @ApiModelProperty( - value = "When the FlowFile was last added to the queue." + value = "How long this FlowFile has been enqueued." ) - public Date getLastQueuedTime() { - return lastQueuedTime; + public Long getQueuedDuration() { + return queuedDuration; } - public void setLastQueuedTime(Date lastQueuedTime) { - this.lastQueuedTime = lastQueuedTime; + public void setQueuedDuration(Long queuedDuration) { + this.queuedDuration = queuedDuration; } /** - * @return when the FlowFile's greatest ancestor entered the flow + * @return duration since the FlowFile's greatest ancestor entered the flow */ - @XmlJavaTypeAdapter(TimestampAdapter.class) @ApiModelProperty( - value = "When the FlowFile's greatest ancestor entered the flow." + value = "Duration since the FlowFile's greatest ancestor entered the flow." ) - public Date getLinageStartDate() { - return linageStartDate; + public Long getLineageDuration() { + return lineageDuration; } - public void setLinageStartDate(Date linageStartDate) { - this.linageStartDate = linageStartDate; + public void setLineageDuration(Long lineageDuration) { + this.lineageDuration = lineageDuration; } /** http://git-wip-us.apache.org/repos/asf/nifi/blob/bbe81981/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/FlowFileSummaries.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/FlowFileSummaries.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/FlowFileSummaries.java index 5a0a3ab..7687d8a 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/FlowFileSummaries.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/FlowFileSummaries.java @@ -68,7 +68,7 @@ public class FlowFileSummaries { case FILENAME: return o1.getFilename().compareTo(o2.getFilename()); case FLOWFILE_AGE: - return o1.getLinageStartDate().compareTo(o2.getLinageStartDate()); + return o1.getLineageDuration().compareTo(o2.getLineageDuration()); case FLOWFILE_SIZE: return Long.compare(o1.getSize(), o2.getSize()); case FLOWFILE_UUID: @@ -78,7 +78,7 @@ public class FlowFileSummaries { case QUEUE_POSITION: return Long.compare(o1.getPosition(), o2.getPosition()); case QUEUED_DURATION: - return o1.getLastQueuedTime().compareTo(o2.getLastQueuedTime()); + return o1.getQueuedDuration().compareTo(o2.getQueuedDuration()); } return 0; http://git-wip-us.apache.org/repos/asf/nifi/blob/bbe81981/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-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java index fe67473..4bc1222 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java @@ -21,6 +21,8 @@ import java.util.Date; import java.util.Set; import org.apache.nifi.controller.ScheduledState; +import org.apache.nifi.controller.queue.SortColumn; +import org.apache.nifi.controller.queue.SortDirection; import org.apache.nifi.controller.repository.claim.ContentDirection; import org.apache.nifi.controller.service.ControllerServiceState; import org.apache.nifi.web.api.dto.BulletinBoardDTO; @@ -583,9 +585,11 @@ public interface NiFiServiceFacade { * @param groupId group * @param connectionId The ID of the connection * @param listingRequestId The ID of the listing request + * @param column sort column + * @param direction sort direction * @return The ListingRequest */ - ListingRequestDTO createFlowFileListingRequest(String groupId, String connectionId, String listingRequestId); + ListingRequestDTO createFlowFileListingRequest(String groupId, String connectionId, String listingRequestId, SortColumn column, SortDirection direction); /** * Gets a new flow file listing request. http://git-wip-us.apache.org/repos/asf/nifi/blob/bbe81981/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-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java index abfd5b8..2f92588 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java @@ -62,6 +62,8 @@ import org.apache.nifi.controller.ProcessorNode; import org.apache.nifi.controller.Snippet; import org.apache.nifi.controller.Template; import org.apache.nifi.controller.label.Label; +import org.apache.nifi.controller.queue.SortColumn; +import org.apache.nifi.controller.queue.SortDirection; import org.apache.nifi.controller.repository.claim.ContentDirection; import org.apache.nifi.controller.status.ConnectionStatus; import org.apache.nifi.controller.status.PortStatus; @@ -1086,8 +1088,8 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { } @Override - public ListingRequestDTO createFlowFileListingRequest(String groupId, String connectionId, String listingRequestId) { - return dtoFactory.createListingRequestDTO(connectionDAO.createFlowFileListingRequest(groupId, connectionId, listingRequestId)); + public ListingRequestDTO createFlowFileListingRequest(String groupId, String connectionId, String listingRequestId, SortColumn column, SortDirection direction) { + return dtoFactory.createListingRequestDTO(connectionDAO.createFlowFileListingRequest(groupId, connectionId, listingRequestId, column, direction)); } @Override http://git-wip-us.apache.org/repos/asf/nifi/blob/bbe81981/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ConnectionResource.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ConnectionResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ConnectionResource.java index 1415846..4b5193f 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ConnectionResource.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ConnectionResource.java @@ -29,6 +29,8 @@ import org.apache.nifi.cluster.manager.exception.UnknownNodeException; import org.apache.nifi.cluster.manager.impl.WebClusterManager; import org.apache.nifi.cluster.node.Node; import org.apache.nifi.cluster.protocol.NodeIdentifier; +import org.apache.nifi.controller.queue.SortColumn; +import org.apache.nifi.controller.queue.SortDirection; import org.apache.nifi.stream.io.StreamUtils; import org.apache.nifi.util.NiFiProperties; import org.apache.nifi.web.ConfigurationSnapshot; @@ -1273,7 +1275,38 @@ public class ConnectionResource extends ApplicationResource { value = "The connection id.", required = true ) - @PathParam("connection-id") String id) { + @PathParam("connection-id") String id, + @ApiParam( + value = "The sort column.", + required = false, + defaultValue = "QUEUE_POSITION", + allowableValues = "QUEUE_POSITION, FLOWFILE_UUID, FILENAME, FLOWFILE_SIZE, QUEUED_DURATION, FLOWFILE_AGE, PENALIZATION" + ) + @FormParam("sortColumn") String sortColumn, + @ApiParam( + value = "The sort direction.", + required = false, + defaultValue = "asc", + allowableValues = "asc, desc" + ) + @FormParam("sortOrder") @DefaultValue("asc") String sortOrder) { + + // parse the sort column + final SortColumn column; + if (sortColumn == null) { + column = SortColumn.QUEUE_POSITION; + } else { + try { + column = SortColumn.valueOf(sortColumn); + } catch (final IllegalArgumentException iae) { + throw new IllegalArgumentException(String.format("Sort Column: Value must be one of [%s]", StringUtils.join(SortColumn.values(), ", "))); + } + } + + // normalize the sort order + if (!sortOrder.equalsIgnoreCase("asc") && !sortOrder.equalsIgnoreCase("desc")) { + throw new IllegalArgumentException("The sort order must be 'asc' or 'desc'."); + } // replicate if cluster manager if (properties.isClusterManager()) { @@ -1287,6 +1320,13 @@ public class ConnectionResource extends ApplicationResource { return generateContinueResponse().build(); } + final SortDirection direction; + if (sortOrder.equalsIgnoreCase("asc")) { + direction = SortDirection.ASCENDING; + } else { + direction = SortDirection.DESCENDING; + } + // ensure the id is the same across the cluster final String listingRequestId; final ClusterContext clusterContext = ClusterContextThreadLocal.getContext(); @@ -1297,7 +1337,7 @@ public class ConnectionResource extends ApplicationResource { } // submit the listing request - final ListingRequestDTO listingRequest = serviceFacade.createFlowFileListingRequest(groupId, id, listingRequestId); + final ListingRequestDTO listingRequest = serviceFacade.createFlowFileListingRequest(groupId, id, listingRequestId, column, direction); populateRemainingFlowFileListingContent(id, listingRequest); // create the revision http://git-wip-us.apache.org/repos/asf/nifi/blob/bbe81981/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-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-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java index 5c3e864..9d02cbc 100644 --- a/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-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java @@ -378,9 +378,10 @@ public final class DtoFactory { if (isListingRequestComplete(listingRequest.getState())) { final List<FlowFileSummary> flowFileSummaries = listingRequest.getFlowFileSummaries(); if (flowFileSummaries != null) { + final Date now = new Date(); final List<FlowFileSummaryDTO> summaryDtos = new ArrayList<>(flowFileSummaries.size()); for (final FlowFileSummary summary : flowFileSummaries) { - summaryDtos.add(createFlowFileSummaryDTO(summary)); + summaryDtos.add(createFlowFileSummaryDTO(summary, now)); } dto.setFlowFileSummaries(summaryDtos); } @@ -395,15 +396,20 @@ public final class DtoFactory { * @param summary summary * @return dto */ - public FlowFileSummaryDTO createFlowFileSummaryDTO(final FlowFileSummary summary) { + public FlowFileSummaryDTO createFlowFileSummaryDTO(final FlowFileSummary summary, final Date now) { final FlowFileSummaryDTO dto = new FlowFileSummaryDTO(); dto.setUuid(summary.getUuid()); dto.setFilename(summary.getFilename()); - dto.setLastQueuedTime(new Date(summary.getLastQueuedTime())); - dto.setLinageStartDate(new Date(summary.getLineageStartDate())); dto.setPenalized(summary.isPenalized()); dto.setPosition(summary.getPosition()); dto.setSize(summary.getSize()); + + final long queuedDuration = now.getTime() - summary.getLastQueuedTime(); + dto.setQueuedDuration(queuedDuration); + + final long age = now.getTime() - summary.getLineageStartDate(); + dto.setLineageDuration(age); + return dto; } @@ -414,14 +420,20 @@ public final class DtoFactory { * @return dto */ public FlowFileDTO createFlowFileDTO(final FlowFileRecord record) { + final Date now = new Date(); final FlowFileDTO dto = new FlowFileDTO(); dto.setUuid(record.getAttribute(CoreAttributes.UUID.key())); dto.setFilename(record.getAttribute(CoreAttributes.FILENAME.key())); - dto.setLastQueuedTime(new Date(record.getLastQueueDate())); - dto.setLinageStartDate(new Date(record.getLineageStartDate())); dto.setPenalized(record.isPenalized()); dto.setSize(record.getSize()); dto.setAttributes(record.getAttributes()); + + final long queuedDuration = now.getTime() - record.getLastQueueDate(); + dto.setQueuedDuration(queuedDuration); + + final long age = now.getTime() - record.getLineageStartDate(); + dto.setLineageDuration(age); + return dto; } http://git-wip-us.apache.org/repos/asf/nifi/blob/bbe81981/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/ConnectionDAO.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/ConnectionDAO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/ConnectionDAO.java index 85cd9b3..932cc23 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/ConnectionDAO.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/ConnectionDAO.java @@ -20,6 +20,8 @@ import java.util.Set; import org.apache.nifi.connectable.Connection; import org.apache.nifi.controller.queue.DropFlowFileStatus; import org.apache.nifi.controller.queue.ListFlowFileStatus; +import org.apache.nifi.controller.queue.SortColumn; +import org.apache.nifi.controller.queue.SortDirection; import org.apache.nifi.controller.repository.FlowFileRecord; import org.apache.nifi.web.DownloadableContent; import org.apache.nifi.web.api.dto.ConnectionDTO; @@ -116,9 +118,11 @@ public interface ConnectionDAO { * @param groupId group id * @param id connection id * @param listingRequestId listing request id + * @param column sort column + * @param direction sort direction * @return The listing request status */ - ListFlowFileStatus createFlowFileListingRequest(String groupId, String id, String listingRequestId); + ListFlowFileStatus createFlowFileListingRequest(String groupId, String id, String listingRequestId, SortColumn column, SortDirection direction); /** * Verifies the listing can be processed. http://git-wip-us.apache.org/repos/asf/nifi/blob/bbe81981/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardConnectionDAO.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardConnectionDAO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardConnectionDAO.java index dca1c18..24601b3 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardConnectionDAO.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardConnectionDAO.java @@ -40,6 +40,8 @@ import org.apache.nifi.controller.exception.ValidationException; import org.apache.nifi.controller.queue.DropFlowFileStatus; import org.apache.nifi.controller.queue.FlowFileQueue; import org.apache.nifi.controller.queue.ListFlowFileStatus; +import org.apache.nifi.controller.queue.SortColumn; +import org.apache.nifi.controller.queue.SortDirection; import org.apache.nifi.controller.repository.ContentNotFoundException; import org.apache.nifi.controller.repository.FlowFileRecord; import org.apache.nifi.flowfile.attributes.CoreAttributes; @@ -373,10 +375,10 @@ public class StandardConnectionDAO extends ComponentDAO implements ConnectionDAO } @Override - public ListFlowFileStatus createFlowFileListingRequest(String groupId, String id, String listingRequestId) { + public ListFlowFileStatus createFlowFileListingRequest(String groupId, String id, String listingRequestId, SortColumn column, SortDirection direction) { final Connection connection = locateConnection(groupId, id); final FlowFileQueue queue = connection.getFlowFileQueue(); - return queue.listFlowFiles(listingRequestId, 100); + return queue.listFlowFiles(listingRequestId, 100, column, direction); } @Override http://git-wip-us.apache.org/repos/asf/nifi/blob/bbe81981/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-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/resources/nifi-web-api-context.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/resources/nifi-web-api-context.xml index 9f3d2f5..406f38c 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/resources/nifi-web-api-context.xml +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/resources/nifi-web-api-context.xml @@ -76,6 +76,7 @@ </bean> <bean id="connectionDAO" class="org.apache.nifi.web.dao.impl.StandardConnectionDAO"> <property name="flowController" ref="flowController"/> + <property name="userService" ref="userService"/> </bean> <bean id="processorDAO" class="org.apache.nifi.web.dao.impl.StandardProcessorDAO"> <property name="flowController" ref="flowController"/> http://git-wip-us.apache.org/repos/asf/nifi/blob/bbe81981/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/pom.xml ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/pom.xml index dc3c448..409afd9 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/pom.xml +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/pom.xml @@ -280,6 +280,7 @@ <include>${staging.dir}/js/nf/canvas/nf-snippet.js</include> <include>${staging.dir}/js/nf/canvas/nf-canvas-toolbox.js</include> <include>${staging.dir}/js/nf/canvas/nf-custom-ui.js</include> + <include>${staging.dir}/js/nf/canvas/nf-queue-listing.js</include> <include>${staging.dir}/js/nf/canvas/nf-controller-service.js</include> <include>${staging.dir}/js/nf/canvas/nf-reporting-task.js</include> <include>${staging.dir}/js/nf/canvas/nf-processor-configuration.js</include> @@ -445,6 +446,7 @@ <include>${staging.dir}/css/remote-process-group-configuration.css</include> <include>${staging.dir}/css/port-configuration.css</include> <include>${staging.dir}/css/port-details.css</include> + <include>${staging.dir}/css/queue-listing.css</include> <include>${staging.dir}/css/label-configuration.css</include> <include>${staging.dir}/css/connection-configuration.css</include> <include>${staging.dir}/css/connection-details.css</include> http://git-wip-us.apache.org/repos/asf/nifi/blob/bbe81981/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/canvas.properties ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/canvas.properties b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/canvas.properties index bf61846..43e60f4 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/canvas.properties +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/resources/filters/canvas.properties @@ -21,6 +21,7 @@ nf.canvas.script.tags=<script type="text/javascript" src="js/nf/nf-namespace.js? <script type="text/javascript" src="js/nf/nf-shell.js?${project.version}"></script>\n\ <script type="text/javascript" src="js/nf/nf-storage.js?${project.version}"></script>\n\ <script type="text/javascript" src="js/nf/canvas/nf-snippet.js?${project.version}"></script>\n\ +<script type="text/javascript" src="js/nf/canvas/nf-queue-listing.js?${project.version}"></script>\n\ <script type="text/javascript" src="js/nf/canvas/nf-canvas-toolbox.js?${project.version}"></script>\n\ <script type="text/javascript" src="js/nf/canvas/nf-custom-ui.js?${project.version}"></script>\n\ <script type="text/javascript" src="js/nf/canvas/nf-controller-service.js?${project.version}"></script>\n\ http://git-wip-us.apache.org/repos/asf/nifi/blob/bbe81981/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/canvas.jsp ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/canvas.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/canvas.jsp index f9970df..337b2b0 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/canvas.jsp +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/pages/canvas.jsp @@ -119,6 +119,8 @@ <jsp:include page="/WEB-INF/partials/canvas/label-configuration.jsp"/> <jsp:include page="/WEB-INF/partials/canvas/connection-configuration.jsp"/> <jsp:include page="/WEB-INF/partials/canvas/drop-request-status-dialog.jsp"/> + <jsp:include page="/WEB-INF/partials/canvas/listing-request-status-dialog.jsp"/> + <jsp:include page="/WEB-INF/partials/canvas/queue-listing.jsp"/> <jsp:include page="/WEB-INF/partials/connection-details.jsp"/> <div id="faded-background"></div> <div id="glass-pane"></div> http://git-wip-us.apache.org/repos/asf/nifi/blob/bbe81981/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/listing-request-status-dialog.jsp ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/listing-request-status-dialog.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/listing-request-status-dialog.jsp new file mode 100644 index 0000000..3320388 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/listing-request-status-dialog.jsp @@ -0,0 +1,29 @@ +<%-- + 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. +--%> +<%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %> +<div id="listing-request-status-dialog"> + <div class="dialog-content"> + <div class="setting"> + <div class="setting-field"> + <div id="listing-request-status-message"></div> + </div> + <div class="setting-field"> + <div id="listing-request-percent-complete"></div> + </div> + </div> + </div> +</div> http://git-wip-us.apache.org/repos/asf/nifi/blob/bbe81981/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/queue-listing.jsp ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/queue-listing.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/queue-listing.jsp new file mode 100644 index 0000000..d00e365 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/queue-listing.jsp @@ -0,0 +1,29 @@ +<%-- + 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. +--%> +<%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %> +<div id="queue-listing-container" class="hidden"> + <div id="queue-listing-header-and-filter"> + <div id="queue-listing-header-text"></div> + </div> + <div id="queue-listing-refresh-container"> + <div id="queue-listing-last-refreshed-container"> + Last updated: <span id="queue-listing-last-refreshed"></span> + </div> + <div id="queue-listing-loading-container" class="loading-container"></div> + </div> + <div id="queue-listing-table"></div> +</div> http://git-wip-us.apache.org/repos/asf/nifi/blob/bbe81981/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/canvas.css ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/canvas.css b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/canvas.css index abb5ebd..2df31d6 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/canvas.css +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/canvas.css @@ -19,6 +19,7 @@ @import url(processor-details.css); @import url(process-group-configuration.css); @import url(process-group-details.css); +@import url(queue-listing.css); @import url(remote-process-group-configuration.css); @import url(controller-service.css); @import url(reporting-task.css); http://git-wip-us.apache.org/repos/asf/nifi/blob/bbe81981/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/dialog.css ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/dialog.css b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/dialog.css index 9f4fefb..86d52fe 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/dialog.css +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/dialog.css @@ -276,10 +276,6 @@ div.go-to-link { z-index: 1301; } -#drop-request-status-message { - -} - #drop-request-percent-complete { margin-top: 10px; width: 378px; @@ -290,6 +286,23 @@ div.go-to-link { border-radius: 0; } +#listing-request-status-dialog { + display: none; + width: 400px; + height: 125px; + z-index: 1301; +} + +#listing-request-percent-complete { + margin-top: 10px; + width: 378px; + border-radius: 0; +} + +#listing-request-percent-complete .ui-progressbar-value { + border-radius: 0; +} + div.progress-label { color: #000000; display: block; http://git-wip-us.apache.org/repos/asf/nifi/blob/bbe81981/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/queue-listing.css ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/queue-listing.css b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/queue-listing.css new file mode 100644 index 0000000..f705ceb --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/queue-listing.css @@ -0,0 +1,86 @@ +/* + * 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. + */ +/* + Queue listing styles +*/ + +#queue-listing-container { + position: absolute; + top: 0px; + bottom: 0px; + left: 0px; + right: 0px; +} + +#queue-listing-header-and-filter { + height: 35px; + margin-top: 20px; + margin-left: 20px; + margin-right: 20px; +} + +#queue-listing-header-text { + float: left; + font-size: 16px; + font-weight: bold; +} + +#queue-listing-refresh-container { + height: 26px; + margin-left: 20px; + margin-right: 20px; + margin-top: 18px; + -webkit-user-select: none; + -moz-user-select: none; +} + +#queue-listing-last-refreshed-container { + float: left; + color: #666; + font-weight: normal; + margin-top: 6px; + margin-left: 3px; +} + +#queue-listing-loading-container { + float: left; + width: 16px; + height: 16px; + background-color: transparent; + margin-top: 4px; + margin-left: 3px; +} + +#queue-listing-last-refreshed { + font-weight: bold; +} + +#queue-listing-header { + padding-top: 10px; +} + +/* queue listing table */ + +#queue-listing-table { + position: absolute; + top: 100px; + left: 20px; + bottom: 20px; + right: 20px; + border: 1px solid #666; + overflow: hidden; +} http://git-wip-us.apache.org/repos/asf/nifi/blob/bbe81981/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/images/iconListQueue.png ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/images/iconListQueue.png b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/images/iconListQueue.png new file mode 100644 index 0000000..9a60eef Binary files /dev/null and b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/images/iconListQueue.png differ http://git-wip-us.apache.org/repos/asf/nifi/blob/bbe81981/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-actions.js ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-actions.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-actions.js index 08f0e42..2f1bbd3 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-actions.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-actions.js @@ -928,7 +928,7 @@ nf.Actions = (function () { // cancel it clearTimeout(dropRequestTimer); - // cancel the provenance + // cancel the drop request completeDropRequest(); } } @@ -1028,8 +1028,8 @@ nf.Actions = (function () { // issue the request to delete the flow files $.ajax({ - type: 'DELETE', - url: connection.component.uri + '/contents', + type: 'POST', + url: connection.component.uri + '/drop-requests', dataType: 'json' }).done(function(response) { // initialize the progress bar value @@ -1045,7 +1045,24 @@ nf.Actions = (function () { } }); }, - + + /** + * Lists the flow files in the specified connection. + * + * @param {selection} selection + */ + listQueue: function (selection) { + if (selection.size() !== 1 || !nf.CanvasUtils.isConnection(selection)) { + return; + } + + // get the connection data + var connection = selection.datum(); + + // list the flow files in the specified connection + nf.QueueListing.listQueue(connection); + }, + /** * Opens the fill color dialog for the component in the specified selection. * http://git-wip-us.apache.org/repos/asf/nifi/blob/bbe81981/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js index 428ddf2..25d7255 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js @@ -1145,6 +1145,7 @@ nf.Canvas = (function () { nf.Search.init(); nf.Settings.init(); nf.Actions.init(); + nf.QueueListing.init(); // initialize the component behaviors nf.Draggable.init(); http://git-wip-us.apache.org/repos/asf/nifi/blob/bbe81981/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-context-menu.js ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-context-menu.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-context-menu.js index d5f49d6..1e7925e 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-context-menu.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-context-menu.js @@ -299,6 +299,16 @@ nf.ContextMenu = (function () { var canEmptyQueue = function (selection) { return nf.Common.isDFM() && isConnection(selection); }; + + /** + * Only DFMs can list a queue. + * + * @param {selection} selection + */ + var canListQueue = function (selection) { + // TODO verify source/destination stopped and 0 active threads + return nf.Common.isDFM() && isConnection(selection) && nf.CanvasUtils.supportsModification(selection); + }; /** * Determines if the components in the specified selection can be moved into a parent group. @@ -402,6 +412,7 @@ nf.ContextMenu = (function () { {condition: isCopyable, menuItem: {img: 'images/iconCopy.png', text: 'Copy', action: 'copy'}}, {condition: isPastable, menuItem: {img: 'images/iconPaste.png', text: 'Paste', action: 'paste'}}, {condition: canMoveToParent, menuItem: {img: 'images/iconMoveToParent.png', text: 'Move to parent group', action: 'moveIntoParent'}}, + {condition: canListQueue, menuItem: {img: 'images/iconListQueue.png', text: 'List queue', action: 'listQueue'}}, {condition: canEmptyQueue, menuItem: {img: 'images/iconEmptyQueue.png', text: 'Empty queue', action: 'emptyQueue'}}, {condition: isDeletable, menuItem: {img: 'images/iconDelete.png', text: 'Delete', action: 'delete'}} ]; http://git-wip-us.apache.org/repos/asf/nifi/blob/bbe81981/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-queue-listing.js ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-queue-listing.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-queue-listing.js new file mode 100644 index 0000000..5336b89 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-queue-listing.js @@ -0,0 +1,435 @@ +/* + * 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 nf */ + +/** + * Lists FlowFiles from a given connection. + */ +nf.QueueListing = (function () { + + var DEFAULT_SORT_COL = 'QUEUE_POSITION'; + var DEFAULT_SORT_ASC = true; + + /** + * Initializes the listing request status dialog. + */ + var initializeListingRequestStatusDialog = function () { + // initialize the listing request progress bar + var listingRequestProgressBar = $('#listing-request-percent-complete').progressbar(); + + // configure the drop request status dialog + $('#listing-request-status-dialog').modal({ + overlayBackground: false, + handler: { + close: function () { + // reset the progress bar + listingRequestProgressBar.find('div.progress-label').remove(); + + // update the progress bar + var label = $('<div class="progress-label"></div>').text('0%'); + listingRequestProgressBar.progressbar('value', 0).append(label); + + // clear the current button model + $('#listing-request-status-dialog').modal('setButtonModel', []); + } + } + }).draggable({ + containment: 'parent', + handle: '.dialog-header' + }); + }; + + /** + * Downloads the content for the provenance event that is currently loaded in the specified direction. + * + * @param {string} direction + */ + var downloadContent = function (direction) { + var connection = $('#queue-listing-table').data('connection'); + + // build the url to the data + var url = config.urls.provenance + '/events/' + encodeURIComponent(eventId) + '/content/' + encodeURIComponent(direction); + + // conditionally include the cluster node id + var clusterNodeId = $('#provenance-event-cluster-node-id').text(); + if (!nf.Common.isBlank(clusterNodeId)) { + window.open(url + '?' + $.param({ + 'clusterNodeId': clusterNodeId + })); + } else { + window.open(url); + } + }; + + /** + * Views the content for the provenance event that is currently loaded in the specified direction. + * + * @param {string} direction + */ + var viewContent = function (direction) { + + // build the uri to the data + var dataUri = controllerUri + '/provenance/events/' + encodeURIComponent(eventId) + '/content/' + encodeURIComponent(direction); + + // conditionally include the cluster node id + var clusterNodeId = $('#provenance-event-cluster-node-id').text(); + if (!nf.Common.isBlank(clusterNodeId)) { + var parameters = { + 'clusterNodeId': clusterNodeId + }; + + dataUri = dataUri + '?' + $.param(parameters); + } + + // open the content viewer + var contentViewerUrl = $('#nifi-content-viewer-url').text(); + + // if there's already a query string don't add another ?... this assumes valid + // input meaning that if the url has already included a ? it also contains at + // least one query parameter + if (contentViewerUrl.indexOf('?') === -1) { + contentViewerUrl += '?'; + } else { + contentViewerUrl += '&'; + } + + // open the content viewer + window.open(contentViewerUrl + $.param({ + 'ref': dataUri + })); + }; + + /** + * Initializes the flowfile details dialog. + */ + var initFlowFileDetailsDialog = function () { + + }; + + /** + * Performs a listing on the specified connection. + * + * @param connection the connection + * @param sortCol the sort column + * @param sortAsc if sort is asc + */ + var performListing = function (connection, sortCol, sortAsc) { + + var MAX_DELAY = 4; + var cancelled = false; + var listingRequest = null; + var listingRequestTimer = null; + + // updates the progress bar + var updateProgress = function (percentComplete) { + // remove existing labels + var progressBar = $('#listing-request-percent-complete'); + progressBar.find('div.progress-label').remove(); + + // update the progress bar + var label = $('<div class="progress-label"></div>').text(percentComplete + '%'); + if (percentComplete > 0) { + label.css('margin-top', '-19px'); + } + progressBar.progressbar('value', percentComplete).append(label); + }; + + // update the button model of the drop request status dialog + $('#listing-request-status-dialog').modal('setButtonModel', [{ + buttonText: 'Stop', + handler: { + click: function () { + cancelled = true; + + // we are waiting for the next poll attempt + if (listingRequestTimer !== null) { + // cancel it + clearTimeout(listingRequestTimer); + + // cancel the listing request + completeListingRequest(); + } + } + } + }]); + + // completes the listing request by removing it + var completeListingRequest = function () { + if (nf.Common.isDefinedAndNotNull(listingRequest)) { + $.ajax({ + type: 'DELETE', + url: listingRequest.uri, + dataType: 'json' + }).always(function() { + $('#listing-request-status-dialog').modal('hide'); + + // use the listing request from when the listing completed + if (nf.Common.isDefinedAndNotNull(listingRequest.flowFileSummaries)) { + var queueListingGrid = $('#queue-listing-table').data('gridInstance'); + var queueListingData = queueListingGrid.getData(); + + // load the flowfiles + queueListingData.beginUpdate(); + queueListingData.setItems(listingRequest.flowFileSummaries, 'uuid'); + queueListingData.endUpdate(); + } else { + if (cancelled === false) { + nf.Dialog.showOkDialog({ + dialogContent: 'The queue has no FlowFiles.', + overlayBackground: false + }); + } + } + }); + } else { + // close the dialog + $('#listing-request-status-dialog').modal('hide'); + } + }; + + // process the listing request + var processListingRequest = function (delay) { + // update the percent complete + updateProgress(listingRequest.percentCompleted); + + // update the status of the listing request + $('#listing-request-status-message').text(listingRequest.state); + + // close the dialog if the + if (listingRequest.finished === true || cancelled === true) { + completeListingRequest(); + } else { + // wait delay to poll again + listingRequestTimer = setTimeout(function () { + // clear the listing request timer + listingRequestTimer = null; + + // schedule to poll the status again in nextDelay + pollListingRequest(Math.min(MAX_DELAY, delay * 2)); + }, delay * 1000); + } + }; + + // schedule for the next poll iteration + var pollListingRequest = function (nextDelay) { + $.ajax({ + type: 'GET', + url: listingRequest.uri, + dataType: 'json' + }).done(function(response) { + listingRequest = response.listingRequest; + processListingRequest(nextDelay); + }).fail(completeListingRequest); + }; + + // issue the request to list the flow files + $.ajax({ + type: 'POST', + url: connection.component.uri + '/listing-requests', + data: { + sortCol: sortCol, + sortDir: sortAsc ? 'asc' : 'desc' + }, + dataType: 'json' + }).done(function(response) { + // initialize the progress bar value + updateProgress(0); + + // show the progress dialog + $('#listing-request-status-dialog').modal('show'); + + // process the drop request + listingRequest = response.listingRequest; + processListingRequest(1); + }).fail(completeListingRequest); + }; + + /** + * Shows the details for the specified flowfile. + * + * @param flowFileSummary the flowfile summary + */ + var showFlowFileDetails = function (flowFileSummary) { + $.ajax({ + type: 'GET', + url: flowFileSummary.uri, + dataType: 'json' + }).done(function(response) { + var flowFile = response.flowfile; + + // show the flowfile details dialog + + }).fail(nf.Common.handleAjaxError); + }; + + /** + * Deletes the specified flowfile. + * + * @param flowFileSummary the flowfile summary + */ + var deleteFlowfile = function (flowFileSummary) { + $.ajax({ + type: 'DELETE', + url: flowFileSummary.uri, + dataType: 'json' + }).done(function(response) { + // get the table and update the row accordingly + var queueListingGrid = $('#queue-listing-table').data('gridInstance'); + var queueListingData = queueListingGrid.getData(); + queueListingData.deleteItem(flowFileSummary.uuid); + }).fail(nf.Common.handleAjaxError); + }; + + /** + * Resets the table size. + */ + var resetTableSize = function () { + var queueListingGrid = $('#queue-listing-table').data('gridInstance'); + if (nf.Common.isDefinedAndNotNull(queueListingGrid)) { + queueListingGrid.resizeCanvas(); + } + }; + + return { + init: function () { + initializeListingRequestStatusDialog(); + initFlowFileDetailsDialog(); + + // listen for browser resize events to update the page size + $(window).resize(function () { + resetTableSize(); + }); + + // define a custom formatter for showing more processor details + var moreDetailsFormatter = function (row, cell, value, columnDef, dataContext) { + return '<img src="images/iconDetails.png" title="View Details" class="pointer show-flowfile-details" style="margin-top: 5px; float: left;"/>'; + }; + + // function for formatting data sizes + var dataSizeFormatter = function (row, cell, value, columnDef, dataContext) { + return nf.Common.formatDataSize(value); + }; + + // function for formatting durations + var formatDuration = function (row, cell, value, columnDef, dataContext) { + return nf.Common.formatDuration(value); + } + + // function for formatting the actions column + var actionFormatter = function (row, cell, value, columnDef, dataContext) { + return '<img src="images/iconDelete.png" title="Delete FlowFile" class="pointer delete-flowfile" style="margin-top: 2px;"/>'; + }; + + // initialize the queue listing table + var flowFileListingColumns = [ + {id: 'moreDetails', field: 'moreDetails', name: ' ', resizable: false, formatter: moreDetailsFormatter, sortable: true, width: 50, maxWidth: 50}, + {id: 'QUEUE_POSITION', name: 'Position', field: 'position', sortable: true, resizable: true}, + {id: 'FLOWFILE_UUID', name: 'UUID', field: 'uuid', sortable: true, resizable: true}, + {id: 'FILENAME', name: 'Filename', field: 'filename', sortable: true, resizable: true}, + {id: 'FLOWFILE_SIZE', name: 'File Size', field: 'size', sortable: true, resizable: true, defaultSortAsc: false, formatter: dataSizeFormatter}, + {id: 'QUEUED_DURATION', name: 'Queued Duration', field: 'queuedDuration', sortable: true, resizable: true, formatter: formatDuration}, + {id: 'FLOWFILE_AGE', name: 'Lineage Duration', field: 'lineageDuration', sortable: true, resizable: true, formatter: formatDuration}, + {id: 'PENALIZATION', name: 'Penalized', field: 'penalized', sortable: true, resizable: true}, + {id: 'actions', name: ' ', sortable: false, resizable: false, formatter: actionFormatter, width: 100, maxWidth: 100} + ]; + + var queueListingOptions = { + forceFitColumns: true, + enableTextSelectionOnCells: true, + enableCellNavigation: false, + enableColumnReorder: false, + autoEdit: false + }; + + // initialize the dataview + var queueListingData = new Slick.Data.DataView({ + inlineFilters: false + }); + queueListingData.setItems([]); + + // initialize the grid + var queueListingGrid = new Slick.Grid('#queue-listing-table', queueListingData, flowFileListingColumns, queueListingOptions); + queueListingGrid.setSelectionModel(new Slick.RowSelectionModel()); + queueListingGrid.registerPlugin(new Slick.AutoTooltips()); + queueListingGrid.setSortColumn(DEFAULT_SORT_COL, DEFAULT_SORT_ASC); + queueListingGrid.onSort.subscribe(function (e, args) { + var connection = $('#queue-listing-table').data('connection'); + performListing(connection, args.sortCol.id, args.sortAsc); + }); + + // configure a click listener + queueListingGrid.onClick.subscribe(function (e, args) { + var target = $(e.target); + + // get the node at this row + var item = queueListingData.getItem(args.row); + + // determine the desired action + if (queueListingGrid.getColumns()[args.cell].id === 'moreDetails') { + if (target.hasClass('show-flowfile-details')) { + showFlowFileDetails(item); + } + } else if (queueListingGrid.getColumns()[args.cell].id === 'actions') { + if (target.hasClass('delete-flowfile')) { + deleteFlowfile(item); + } + } + }); + + // wire up the dataview to the grid + queueListingData.onRowCountChanged.subscribe(function (e, args) { + queueListingGrid.updateRowCount(); + queueListingGrid.render(); + + // update the total number of displayed processors + $('#displayed-flowfiles').text(args.current); + }); + queueListingData.onRowsChanged.subscribe(function (e, args) { + queueListingGrid.invalidateRows(args.rows); + queueListingGrid.render(); + }); + + // hold onto an instance of the grid + $('#queue-listing-table').data('gridInstance', queueListingGrid); + + // initialize the number of display items + $('#displayed-flowfiles').text('0'); + }, + + /** + * Shows the listing of the FlowFiles from a given connection. + * + * @param {object} The connection + */ + listQueue: function (connection) { + // show the listing container + nf.Shell.showContent('#queue-listing-container').done(function () { + $('#queue-listing-table').removeData('connection'); + }); + + // adjust the table size + resetTableSize(); + + // store the connection for access later + $('#queue-listing-table').data('connection', connection); + + // perform the initial listing + performListing(connection, DEFAULT_SORT_COL, DEFAULT_SORT_ASC); + } + }; +}()); \ No newline at end of file
