You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by mc...@apache.org on 2015/01/08 17:19:53 UTC
incubator-nifi git commit: NIFI-115: - Code clean up. - Showing an
expiration icon on the connection label when appropriate. - Allowing the user
to search for connections that have expiration and back pressure configured.
Repository: incubator-nifi
Updated Branches:
refs/heads/develop 22596080c -> bda9985d6
NIFI-115:
- Code clean up.
- Showing an expiration icon on the connection label when appropriate.
- Allowing the user to search for connections that have expiration and back pressure configured.
Project: http://git-wip-us.apache.org/repos/asf/incubator-nifi/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-nifi/commit/bda9985d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-nifi/tree/bda9985d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-nifi/diff/bda9985d
Branch: refs/heads/develop
Commit: bda9985d6a3f7ecb2f20829eb2f084a8bfdd56fe
Parents: 2259608
Author: Matt Gilman <ma...@gmail.com>
Authored: Thu Jan 8 11:02:25 2015 -0500
Committer: Matt Gilman <ma...@gmail.com>
Committed: Thu Jan 8 11:02:25 2015 -0500
----------------------------------------------------------------------
.../nifi/web/controller/ControllerFacade.java | 23 ++
.../canvas/connection-configuration.jsp | 2 +-
.../WEB-INF/partials/connection-details.jsp | 2 +-
.../src/main/webapp/js/nf/canvas/nf-canvas.js | 275 +++++++++++--------
.../main/webapp/js/nf/canvas/nf-connection.js | 107 ++++++--
5 files changed, 269 insertions(+), 140 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/bda9985d/nar-bundles/framework-bundle/framework/web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java b/nar-bundles/framework-bundle/framework/web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
index 008295c..dbc4b3c 100644
--- a/nar-bundles/framework-bundle/framework/web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
+++ b/nar-bundles/framework-bundle/framework/web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
@@ -113,6 +113,7 @@ import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.admin.service.UserService;
import org.apache.nifi.authorization.DownloadAuthorization;
+import org.apache.nifi.processor.DataUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.AccessDeniedException;
@@ -1254,6 +1255,28 @@ public class ControllerFacade implements ControllerServiceProvider {
for (final FlowFilePrioritizer comparator : queue.getPriorities()) {
addIfAppropriate(searchStr, comparator.getClass().getName(), "Prioritizer", matches);
}
+
+ // search expiration
+ if (StringUtils.containsIgnoreCase("expires", searchStr) || StringUtils.containsIgnoreCase("expiration", searchStr)) {
+ final int expirationMillis = connection.getFlowFileQueue().getFlowFileExpiration(TimeUnit.MILLISECONDS);
+ if (expirationMillis > 0) {
+ matches.add("FlowFile expiration: " + connection.getFlowFileQueue().getFlowFileExpiration());
+ }
+ }
+
+ // search back pressure
+ if (StringUtils.containsIgnoreCase("back pressure", searchStr) || StringUtils.containsIgnoreCase("pressure", searchStr)) {
+ final String backPressureDataSize = connection.getFlowFileQueue().getBackPressureDataSizeThreshold();
+ final Double backPressureBytes = DataUnit.parseDataSize(backPressureDataSize, DataUnit.B);
+ if (backPressureBytes > 0) {
+ matches.add("Back pressure data size: " + backPressureDataSize);
+ }
+
+ final long backPressureCount = connection.getFlowFileQueue().getBackPressureObjectThreshold();
+ if (backPressureCount > 0) {
+ matches.add("Back pressure count: " + backPressureCount);
+ }
+ }
// search the source
final Connectable source = connection.getSource();
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/bda9985d/nar-bundles/framework-bundle/framework/web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/connection-configuration.jsp
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/connection-configuration.jsp b/nar-bundles/framework-bundle/framework/web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/connection-configuration.jsp
index eaea170..045b9e9 100644
--- a/nar-bundles/framework-bundle/framework/web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/connection-configuration.jsp
+++ b/nar-bundles/framework-bundle/framework/web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/connection-configuration.jsp
@@ -35,7 +35,7 @@
</div>
<div class="setting">
<div class="setting-name">
- File expiration
+ FlowFile expiration
<img class="setting-icon icon-info" src="images/iconInfo.png" alt="Info" title="The maximum amount of time an object may be in the flow before it will be automatically aged out of the flow."/>
</div>
<div class="setting-field">
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/bda9985d/nar-bundles/framework-bundle/framework/web/nifi-web-ui/src/main/webapp/WEB-INF/partials/connection-details.jsp
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/web/nifi-web-ui/src/main/webapp/WEB-INF/partials/connection-details.jsp b/nar-bundles/framework-bundle/framework/web/nifi-web-ui/src/main/webapp/WEB-INF/partials/connection-details.jsp
index 5e39020..d985de1 100644
--- a/nar-bundles/framework-bundle/framework/web/nifi-web-ui/src/main/webapp/WEB-INF/partials/connection-details.jsp
+++ b/nar-bundles/framework-bundle/framework/web/nifi-web-ui/src/main/webapp/WEB-INF/partials/connection-details.jsp
@@ -75,7 +75,7 @@
</div>
<div class="setting">
<div class="setting-name">
- File expiration
+ FlowFile expiration
<img class="setting-icon icon-info" src="images/iconInfo.png" alt="Info" title="The maximum amount of time an object may be in the flow before it will be automatically aged out of the flow."/>
</div>
<div class="setting-field">
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/bda9985d/nar-bundles/framework-bundle/framework/web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js b/nar-bundles/framework-bundle/framework/web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js
index eb16ad9..42c7f45 100644
--- a/nar-bundles/framework-bundle/framework/web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js
+++ b/nar-bundles/framework-bundle/framework/web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas.js
@@ -311,6 +311,28 @@ nf.Canvas = (function () {
'offset': '100%',
'stop-color': '#ffffff'
});
+
+ // define the gradient for the expiration icon
+ var expirationBackground = defs.append('linearGradient')
+ .attr({
+ 'id': 'expiration',
+ 'x1': '0%',
+ 'y1': '0%',
+ 'x2': '0%',
+ 'y2': '100%'
+ });
+
+ expirationBackground.append('stop')
+ .attr({
+ 'offset': '0%',
+ 'stop-color': '#aeafb1'
+ });
+
+ expirationBackground.append('stop')
+ .attr({
+ 'offset': '100%',
+ 'stop-color': '#87888a'
+ });
// create the canvas element
canvas = svg.append('g')
@@ -322,135 +344,135 @@ nf.Canvas = (function () {
// handle canvas events
svg.on('mousedown.selection', function () {
- canvasClicked = true;
+ canvasClicked = true;
- if (d3.event.button !== 0) {
- // prevent further propagation (to parents and others handlers
- // on the same element to prevent zoom behavior)
- d3.event.stopImmediatePropagation();
- return;
+ if (d3.event.button !== 0) {
+ // prevent further propagation (to parents and others handlers
+ // on the same element to prevent zoom behavior)
+ d3.event.stopImmediatePropagation();
+ return;
+ }
+
+ // show selection box if shift is held down
+ if (d3.event.shiftKey) {
+ var position = d3.mouse(canvas.node());
+ canvas.append('rect')
+ .attr('rx', 6)
+ .attr('ry', 6)
+ .attr('x', position[0])
+ .attr('y', position[1])
+ .attr('class', 'selection')
+ .attr('width', 0)
+ .attr('height', 0)
+ .attr('stroke-width', function () {
+ return 1 / nf.Canvas.View.scale();
+ })
+ .attr('stroke-dasharray', function () {
+ return 4 / nf.Canvas.View.scale();
+ })
+ .datum(position);
+
+ // prevent further propagation (to parents)
+ d3.event.stopPropagation();
+ }
+ })
+ .on('mousemove.selection', function () {
+ // update selection box if shift is held down
+ if (d3.event.shiftKey) {
+ // get the selection box
+ var selectionBox = d3.select('rect.selection');
+ if (!selectionBox.empty()) {
+ // get the original position
+ var originalPosition = selectionBox.datum();
+ var position = d3.mouse(canvas.node());
+
+ var d = {};
+ if (originalPosition[0] < position[0]) {
+ d.x = originalPosition[0];
+ d.width = position[0] - originalPosition[0];
+ } else {
+ d.x = position[0];
+ d.width = originalPosition[0] - position[0];
}
- // show selection box if shift is held down
- if (d3.event.shiftKey) {
- var position = d3.mouse(canvas.node());
- canvas.append('rect')
- .attr('rx', 6)
- .attr('ry', 6)
- .attr('x', position[0])
- .attr('y', position[1])
- .attr('class', 'selection')
- .attr('width', 0)
- .attr('height', 0)
- .attr('stroke-width', function () {
- return 1 / nf.Canvas.View.scale();
- })
- .attr('stroke-dasharray', function () {
- return 4 / nf.Canvas.View.scale();
- })
- .datum(position);
-
- // prevent further propagation (to parents)
- d3.event.stopPropagation();
+ if (originalPosition[1] < position[1]) {
+ d.y = originalPosition[1];
+ d.height = position[1] - originalPosition[1];
+ } else {
+ d.y = position[1];
+ d.height = originalPosition[1] - position[1];
}
- })
- .on('mousemove.selection', function () {
- // update selection box if shift is held down
- if (d3.event.shiftKey) {
- // get the selection box
- var selectionBox = d3.select('rect.selection');
- if (!selectionBox.empty()) {
- // get the original position
- var originalPosition = selectionBox.datum();
- var position = d3.mouse(canvas.node());
-
- var d = {};
- if (originalPosition[0] < position[0]) {
- d.x = originalPosition[0];
- d.width = position[0] - originalPosition[0];
- } else {
- d.x = position[0];
- d.width = originalPosition[0] - position[0];
- }
- if (originalPosition[1] < position[1]) {
- d.y = originalPosition[1];
- d.height = position[1] - originalPosition[1];
- } else {
- d.y = position[1];
- d.height = originalPosition[1] - position[1];
- }
+ // update the selection box
+ selectionBox.attr(d);
+ }
- // update the selection box
- selectionBox.attr(d);
- }
+ d3.event.stopPropagation();
+ }
+ })
+ .on('mouseup.selection', function () {
+ // ensure this originated from clicking the canvas, not a component.
+ // when clicking on a component, the event propagation is stopped so
+ // it never reaches the canvas. we cannot do this however on up events
+ // since the drag events break down
+ if (canvasClicked === false) {
+ return;
+ }
- d3.event.stopPropagation();
- }
- })
- .on('mouseup.selection', function () {
- // ensure this originated from clicking the canvas, not a component.
- // when clicking on a component, the event propagation is stopped so
- // it never reaches the canvas. we cannot do this however on up events
- // since the drag events break down
- if (canvasClicked === false) {
- return;
- }
+ // reset the canvas click flag
+ canvasClicked = false;
- // reset the canvas click flag
- canvasClicked = false;
+ // hide the context menu if necessary
+ nf.ContextMenu.hide();
- // hide the context menu if necessary
- nf.ContextMenu.hide();
-
- // get the selection box
- var selectionBox = d3.select('rect.selection');
- if (!selectionBox.empty()) {
- var selectionBoundingBox = {
- x: parseInt(selectionBox.attr('x'), 10),
- y: parseInt(selectionBox.attr('y'), 10),
- width: parseInt(selectionBox.attr('width'), 10),
- height: parseInt(selectionBox.attr('height'), 10)
- };
+ // get the selection box
+ var selectionBox = d3.select('rect.selection');
+ if (!selectionBox.empty()) {
+ var selectionBoundingBox = {
+ x: parseInt(selectionBox.attr('x'), 10),
+ y: parseInt(selectionBox.attr('y'), 10),
+ width: parseInt(selectionBox.attr('width'), 10),
+ height: parseInt(selectionBox.attr('height'), 10)
+ };
- // see if a component should be selected or not
- d3.selectAll('g.component').classed('selected', function (d) {
- // consider it selected if its already selected or enclosed in the bounding box
- return d3.select(this).classed('selected') ||
- d.component.position.x >= selectionBoundingBox.x && (d.component.position.x + d.dimensions.width) <= (selectionBoundingBox.x + selectionBoundingBox.width) &&
- d.component.position.y >= selectionBoundingBox.y && (d.component.position.y + d.dimensions.height) <= (selectionBoundingBox.y + selectionBoundingBox.height);
- });
-
- // see if a connection should be selected or not
- d3.selectAll('g.connection').classed('selected', function (d) {
- // consider all points
- var points = [d.start].concat(d.bends, [d.end]);
-
- // determine the bounding box
- var x = d3.extent(points, function (pt) {
- return pt.x;
- });
- var y = d3.extent(points, function (pt) {
- return pt.y;
- });
+ // see if a component should be selected or not
+ d3.selectAll('g.component').classed('selected', function (d) {
+ // consider it selected if its already selected or enclosed in the bounding box
+ return d3.select(this).classed('selected') ||
+ d.component.position.x >= selectionBoundingBox.x && (d.component.position.x + d.dimensions.width) <= (selectionBoundingBox.x + selectionBoundingBox.width) &&
+ d.component.position.y >= selectionBoundingBox.y && (d.component.position.y + d.dimensions.height) <= (selectionBoundingBox.y + selectionBoundingBox.height);
+ });
- // consider it selected if its already selected or enclosed in the bounding box
- return d3.select(this).classed('selected') ||
- x[0] >= selectionBoundingBox.x && x[1] <= (selectionBoundingBox.x + selectionBoundingBox.width) &&
- y[0] >= selectionBoundingBox.y && y[1] <= (selectionBoundingBox.y + selectionBoundingBox.height);
- });
-
- // remove the selection box
- selectionBox.remove();
- } else if (panning === false) {
- // deselect as necessary if we are not panning
- nf.CanvasUtils.getSelection().classed('selected', false);
- }
+ // see if a connection should be selected or not
+ d3.selectAll('g.connection').classed('selected', function (d) {
+ // consider all points
+ var points = [d.start].concat(d.bends, [d.end]);
- // update the toolbar
- nf.CanvasToolbar.refresh();
+ // determine the bounding box
+ var x = d3.extent(points, function (pt) {
+ return pt.x;
+ });
+ var y = d3.extent(points, function (pt) {
+ return pt.y;
+ });
+
+ // consider it selected if its already selected or enclosed in the bounding box
+ return d3.select(this).classed('selected') ||
+ x[0] >= selectionBoundingBox.x && x[1] <= (selectionBoundingBox.x + selectionBoundingBox.width) &&
+ y[0] >= selectionBoundingBox.y && y[1] <= (selectionBoundingBox.y + selectionBoundingBox.height);
});
+ // remove the selection box
+ selectionBox.remove();
+ } else if (panning === false) {
+ // deselect as necessary if we are not panning
+ nf.CanvasUtils.getSelection().classed('selected', false);
+ }
+
+ // update the toolbar
+ nf.CanvasToolbar.refresh();
+ });
+
// define a function for update the graph dimensions
var updateGraphSize = function () {
// get the location of the bottom of the graph
@@ -802,17 +824,21 @@ nf.Canvas = (function () {
};
return {
+
CANVAS_OFFSET: 0,
+
/**
* Determines if the current broswer supports SVG.
*/
SUPPORTS_SVG: !!document.createElementNS && !!document.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGRect,
+
/**
* Hides the splash that is displayed while the application is loading.
*/
hideSplash: function () {
$('#splash').fadeOut();
},
+
/**
* Stop polling for revision.
*/
@@ -820,6 +846,7 @@ nf.Canvas = (function () {
// set polling flag
revisionPolling = false;
},
+
/**
* Remove the status poller.
*/
@@ -827,6 +854,7 @@ nf.Canvas = (function () {
// set polling flag
statusPolling = false;
},
+
/**
* Reloads the flow from the server based on the currently specified group id.
* To load another group, update nf.Canvas.setGroupId and call nf.Canvas.reload.
@@ -865,6 +893,7 @@ nf.Canvas = (function () {
});
}).promise();
},
+
/**
* Reloads the status.
*/
@@ -878,6 +907,7 @@ nf.Canvas = (function () {
});
}).promise();
},
+
/**
* Initialize NiFi.
*/
@@ -999,6 +1029,7 @@ nf.Canvas = (function () {
}).fail(nf.Common.handleAjaxError);
}).fail(nf.Common.handleAjaxError);
},
+
/**
* Defines the gradient colors used to render processors.
*
@@ -1007,6 +1038,7 @@ nf.Canvas = (function () {
defineProcessorColors: function (colors) {
setColors(colors, 'processor');
},
+
/**
* Defines the gradient colors used to render label.
*
@@ -1015,6 +1047,7 @@ nf.Canvas = (function () {
defineLabelColors: function (colors) {
setColors(colors, 'label');
},
+
/**
* Return whether this instance of NiFi is clustered.
*
@@ -1023,12 +1056,14 @@ nf.Canvas = (function () {
isClustered: function () {
return clustered === true;
},
+
/**
* Returns whether site to site communications is secure.
*/
isSecureSiteToSite: function () {
return secureSiteToSite;
},
+
/**
* Set the group id.
*
@@ -1043,6 +1078,7 @@ nf.Canvas = (function () {
getGroupId: function () {
return groupId;
},
+
/**
* Set the group name.
*
@@ -1051,12 +1087,14 @@ nf.Canvas = (function () {
setGroupName: function (gn) {
groupName = gn;
},
+
/**
* Get the group name.
*/
getGroupName: function () {
return groupName;
},
+
/**
* Set the parent group id.
*
@@ -1065,13 +1103,16 @@ nf.Canvas = (function () {
setParentGroupId: function (pgi) {
parentGroupId = pgi;
},
+
/**
* Get the parent group id.
*/
getParentGroupId: function () {
return parentGroupId;
},
+
View: (function () {
+
/**
* Updates component visibility based on their proximity to the screen's viewport.
*/
@@ -1138,8 +1179,8 @@ nf.Canvas = (function () {
.classed('entering', function () {
return visible && !wasVisible;
}).classed('leaving', function () {
- return !visible && wasVisible;
- });
+ return !visible && wasVisible;
+ });
};
// get the all components
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/bda9985d/nar-bundles/framework-bundle/framework/web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-connection.js
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-connection.js b/nar-bundles/framework-bundle/framework/web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-connection.js
index 0b0c40a..8da9f6a 100644
--- a/nar-bundles/framework-bundle/framework/web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-connection.js
+++ b/nar-bundles/framework-bundle/framework/web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-connection.js
@@ -186,6 +186,24 @@ nf.Connection = (function () {
var isGroup = function (terminal) {
return terminal.groupId !== nf.Canvas.getGroupId() && (isInputPortType(terminal.type) || isOutputPortType(terminal.type));
};
+
+ /**
+ * Determines whether expiration is configured for the specified connection.
+ *
+ * @param {object} connection
+ * @return {boolean} Whether expiration is configured
+ */
+ var isExpirationConfigured = function (connection) {
+ if (nf.Common.isDefinedAndNotNull(connection.flowFileExpiration)) {
+ var match = connection.flowFileExpiration.match(/^(\d+).*/);
+ if (match !== null && match.length > 0) {
+ if (parseInt(match[0], 10) > 0) {
+ return true;
+ }
+ }
+ }
+ return false;
+ };
/**
* Sorts the specified connections according to the z index.
@@ -325,16 +343,16 @@ nf.Connection = (function () {
return grouped;
})
- .classed('ghost', function (d) {
- var ghost = false;
+ .classed('ghost', function (d) {
+ var ghost = false;
- // if the connection has a relationship that is unavailable, mark it a ghost relationship
- if (hasUnavailableRelationship(d)) {
- ghost = true;
- }
+ // if the connection has a relationship that is unavailable, mark it a ghost relationship
+ if (hasUnavailableRelationship(d)) {
+ ghost = true;
+ }
- return ghost;
- });
+ return ghost;
+ });
}
updated.each(function (d) {
@@ -669,7 +687,7 @@ nf.Connection = (function () {
// update the label text
connectionFrom.select('text.connection-from')
- .each(function (d) {
+ .each(function () {
var connectionFromLabel = d3.select(this);
// reset the label name to handle any previous state
@@ -677,9 +695,9 @@ nf.Connection = (function () {
// apply ellipsis to the label as necessary
nf.CanvasUtils.ellipsis(connectionFromLabel, d.component.source.name);
- }).append('title').text(function (d) {
- return d.component.source.name;
- });
+ }).append('title').text(function () {
+ return d.component.source.name;
+ });
// update the label run status
connectionFrom.select('image.connection-from-run-status').attr('xlink:href', function () {
@@ -758,8 +776,8 @@ nf.Connection = (function () {
// apply ellipsis to the label as necessary
nf.CanvasUtils.ellipsis(connectionToLabel, d.component.destination.name);
}).append('title').text(function (d) {
- return d.component.destination.name;
- });
+ return d.component.destination.name;
+ });
// update the label run status
connectionTo.select('image.connection-to-run-status').attr('xlink:href', function () {
@@ -821,7 +839,7 @@ nf.Connection = (function () {
// update the connection name
connectionName.select('text.connection-name')
- .each(function (d) {
+ .each(function () {
var connectionToLabel = d3.select(this);
// reset the label name to handle any previous state
@@ -829,9 +847,9 @@ nf.Connection = (function () {
// apply ellipsis to the label as necessary
nf.CanvasUtils.ellipsis(connectionToLabel, connectionNameValue);
- }).append('title').text(function (d) {
- return connectionNameValue;
- });
+ }).append('title').text(function () {
+ return connectionNameValue;
+ });
} else {
// there is no connection name, but check if the name was previous
// rendered so it can be removed
@@ -861,11 +879,49 @@ nf.Connection = (function () {
.text('Queued');
queued.append('text')
+ .attr({
+ 'class': 'connection-stats-value queued',
+ 'x': 46,
+ 'y': 10
+ });
+
+ var expiration = queued.append('g')
.attr({
- 'class': 'connection-stats-value queued',
- 'x': 46,
- 'y': 10
+ 'class': 'expiration-icon',
+ 'transform': 'translate(167, 2)'
});
+
+ expiration.append('circle')
+ .attr({
+ 'cx': 5,
+ 'cy': 5,
+ 'r': 4.75,
+ 'stroke-width': 0.5,
+ 'stroke': '#87888a',
+ 'fill': 'url(#expiration)'
+ });
+
+ expiration.append('line')
+ .attr({
+ 'x1': 6,
+ 'y1': 5,
+ 'x2': 3,
+ 'y2': 4,
+ 'stroke': '#fff',
+ 'stroke-width': 1
+ });
+
+ expiration.append('line')
+ .attr({
+ 'x1': 6,
+ 'y1': 5,
+ 'x2': 3,
+ 'y2': 7,
+ 'stroke': '#fff',
+ 'stroke-width': 1
+ });
+
+ expiration.append('title');
}
// update the queued vertical positioning as necessary
@@ -879,6 +935,15 @@ nf.Connection = (function () {
.attr('height', function () {
return 5 + (15 * labelCount) + 3;
});
+
+ // determine whether or not to show the expiration icon
+ connectionLabelContainer.select('g.expiration-icon')
+ .classed('hidden', function () {
+ return !isExpirationConfigured(d.component);
+ })
+ .select('title').text(function () {
+ return 'Expires FlowFiles older than ' + d.component.flowFileExpiration;
+ });
if (nf.Common.isDFM()) {
// only support dragging the label when appropriate