http://git-wip-us.apache.org/repos/asf/nifi/blob/8b27ed90/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/provenance/nf-provenance-lineage.js
----------------------------------------------------------------------
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/provenance/nf-provenance-lineage.js
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/provenance/nf-provenance-lineage.js
index a8d04ba..5bf3892 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/provenance/nf-provenance-lineage.js
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/provenance/nf-provenance-lineage.js
@@ -40,7 +40,6 @@ nf.ProvenanceLineage = (function () {
// initialize the dialog
$('#lineage-query-dialog').modal({
headerText: 'Computing FlowFile lineage...',
- overlayBackground: false,
handler: {
close: function () {
// reset the progress bar
@@ -57,9 +56,9 @@ nf.ProvenanceLineage = (function () {
/**
* Appends the items to the context menu.
- *
+ *
* items = [{class: ..., text: ..., click: function() {...}}, ...]
- *
+ *
* @param {array} items
*/
var addContextMenuItems = function (items) {
@@ -83,7 +82,7 @@ nf.ProvenanceLineage = (function () {
/**
* Shows the details for the specified event.
- *
+ *
* @param {string} eventId
* @param {string} clusterNodeId The id of the node in the cluster
where this event/flowfile originated
*/
@@ -95,7 +94,7 @@ nf.ProvenanceLineage = (function () {
/**
* Gets the details for the specified event.
- *
+ *
* @param {string} eventId
* @param {string} clusterNodeId The id of the node in the cluster
where this event/flowfile originated
*/
@@ -103,8 +102,8 @@ nf.ProvenanceLineage = (function () {
var url;
if (nf.Common.isDefinedAndNotNull(clusterNodeId)) {
url = config.urls.events + encodeURIComponent(eventId) + '?' +
$.param({
- clusterNodeId: clusterNodeId
- });
+ clusterNodeId: clusterNodeId
+ });
} else {
url = config.urls.events + encodeURIComponent(eventId);
}
@@ -118,7 +117,7 @@ nf.ProvenanceLineage = (function () {
/**
* Submits the specified lineage request.
- *
+ *
* @param {type} lineageRequest
* @returns {deferred}
*/
@@ -128,7 +127,7 @@ nf.ProvenanceLineage = (function () {
'request': lineageRequest
}
};
-
+
return $.ajax({
type: 'POST',
url: config.urls.lineage,
@@ -140,7 +139,7 @@ nf.ProvenanceLineage = (function () {
/**
* Gets the specified lineage.
- *
+ *
* @param {type} lineage
* @returns {deferred}
*/
@@ -148,8 +147,8 @@ nf.ProvenanceLineage = (function () {
var url = lineage.uri;
if (nf.Common.isDefinedAndNotNull(lineage.clusterNodeId)) {
url += '?' + $.param({
- clusterNodeId: lineage.clusterNodeId
- });
+ clusterNodeId: lineage.clusterNodeId
+ });
}
return $.ajax({
@@ -161,7 +160,7 @@ nf.ProvenanceLineage = (function () {
/**
* Cancels the specified lineage.
- *
+ *
* @param {type} lineage
* @returns {deferred}
*/
@@ -169,8 +168,8 @@ nf.ProvenanceLineage = (function () {
var url = lineage.uri;
if (nf.Common.isDefinedAndNotNull(lineage.clusterNodeId)) {
url += '?' + $.param({
- clusterNodeId: lineage.clusterNodeId
- });
+ clusterNodeId: lineage.clusterNodeId
+ });
}
return $.ajax({
@@ -185,7 +184,7 @@ nf.ProvenanceLineage = (function () {
/**
* Renders the lineage in the specified results.
- *
+ *
* @param {object} lineageResults
* @param {integer} eventId
* @param {string} clusterNodeId The id of the node in the cluster
where this event/flowfile originated
@@ -535,90 +534,90 @@ nf.ProvenanceLineage = (function () {
// handle zoom behavior
var lineageZoom = d3.behavior.zoom()
- .scaleExtent([0.2, 8])
- .on('zoom', function () {
- d3.select('g.lineage').attr('transform', function () {
- return 'translate(' + d3.event.translate + ') scale('
+ d3.event.scale + ')';
- });
+ .scaleExtent([0.2, 8])
+ .on('zoom', function () {
+ d3.select('g.lineage').attr('transform', function () {
+ return 'translate(' + d3.event.translate + ') scale(' +
d3.event.scale + ')';
});
+ });
// build the svg img
var svg = d3.select('#provenance-lineage-container').append('svg:svg')
- .attr('width', width)
- .attr('height', height)
- .style({
- 'font-family': 'Verdana, Arial, sans-serif',
- 'font-size': '10px'
- })
- .call(lineageZoom)
- .on('dblclick.zoom', null)
- .on('mousedown', function (d) {
- // hide the context menu if necessary
- d3.selectAll('circle.context').classed('context', false);
- $('#provenance-lineage-context-menu').hide().empty();
- })
- .on('contextmenu', function () {
- var contextMenu = $('#provenance-lineage-context-menu');
-
- // if there is something to show in the context menu
- if (!contextMenu.is(':empty')) {
- var position = d3.mouse(this);
-
- // show the context menu
- contextMenu.css({
- 'left': position[0] + 'px',
- 'top': position[1] + 'px'
- }).show();
- }
+ .attr('width', width)
+ .attr('height', height)
+ .style({
+ 'font-family': 'Verdana, Arial, sans-serif',
+ 'font-size': '10px'
+ })
+ .call(lineageZoom)
+ .on('dblclick.zoom', null)
+ .on('mousedown', function (d) {
+ // hide the context menu if necessary
+ d3.selectAll('circle.context').classed('context', false);
+ $('#provenance-lineage-context-menu').hide().empty();
+ })
+ .on('contextmenu', function () {
+ var contextMenu = $('#provenance-lineage-context-menu');
+
+ // if there is something to show in the context menu
+ if (!contextMenu.is(':empty')) {
+ var position = d3.mouse(this);
+
+ // show the context menu
+ contextMenu.css({
+ 'left': position[0] + 'px',
+ 'top': position[1] + 'px'
+ }).show();
+ }
- // prevent the native default context menu
- d3.event.preventDefault();
- });
+ // prevent the native default context menu
+ d3.event.preventDefault();
+ });
svg.append('rect')
- .attr({
- 'width': '100%',
- 'height': '100%',
- 'fill': '#fff'
- });
+ .attr({
+ 'width': '100%',
+ 'height': '100%',
+ 'fill': '#fff'
+ });
svg.append('defs').selectAll('marker')
- .data(['FLOWFILE', 'FLOWFILE-SELECTED', 'EVENT',
'EVENT-SELECTED'])
- .enter().append('marker')
- .attr({
- 'id': function (d) {
- return d;
- },
- 'viewBox': '0 -3 6 6',
- 'refX': function (d) {
- if (d.indexOf('FLOWFILE') >= 0) {
- return 16;
- } else {
- return 11;
- }
- },
- 'refY': 0,
- 'markerWidth': 6,
- 'markerHeight': 6,
- 'orient': 'auto',
- 'fill': function (d) {
- if (d.indexOf('SELECTED') >= 0) {
- return '#FFCC00';
- } else {
- return '#000000';
- }
+ .data(['FLOWFILE', 'FLOWFILE-SELECTED', 'EVENT', 'EVENT-SELECTED'])
+ .enter().append('marker')
+ .attr({
+ 'id': function (d) {
+ return d;
+ },
+ 'viewBox': '0 -3 6 6',
+ 'refX': function (d) {
+ if (d.indexOf('FLOWFILE') >= 0) {
+ return 16;
+ } else {
+ return 11;
}
- })
- .append('path')
- .attr('d', 'M0,-3 L6,0 L0,3');
+ },
+ 'refY': 0,
+ 'markerWidth': 6,
+ 'markerHeight': 6,
+ 'orient': 'auto',
+ 'fill': function (d) {
+ if (d.indexOf('SELECTED') >= 0) {
+ return '#FFCC00';
+ } else {
+ return '#000000';
+ }
+ }
+ })
+ .append('path')
+ .attr('d', 'M0,-3 L6,0 L0,3');
// group everything together
var lineageContainer = svg.append('g')
- .attr({
- 'transform': 'translate(0, 0) scale(1)',
- 'pointer-events': 'all',
- 'class': 'lineage'
- });
+ .attr({
+ 'transform': 'translate(0, 0) scale(1)',
+ 'pointer-events': 'all',
+ 'class': 'lineage'
+ });
// select the nodes and links
var nodes = lineageContainer.selectAll('g.node');
@@ -679,445 +678,450 @@ nf.ProvenanceLineage = (function () {
// node
flowfiles.append('circle')
- .attr({
- 'r': 16,
- 'fill': '#D4E0E5',
- 'stroke': '#000',
- 'stroke-width': 1.0
- })
- .on('mousedown', function (d) {
- // empty context menu if necessary
- $('#provenance-lineage-context-menu').hide().empty();
-
- // prevents the drag event when something other than
the
- // left button is clicked
- if (d3.event.button !== 0) {
- d3.event.stopPropagation();
- }
- }, true)
- .on('mouseover', function (d) {
- links.filter(function (linkDatum) {
- return d.id === linkDatum.flowFileUuid;
- })
- .classed('selected', true)
- .attr('marker-end', function (d) {
- return 'url(#' + d.target.type +
'-SELECTED)';
- });
+ .attr({
+ 'r': 16,
+ 'fill': '#D4E0E5',
+ 'stroke': '#000',
+ 'stroke-width': 1.0
+ })
+ .on('mousedown', function (d) {
+ // empty context menu if necessary
+ $('#provenance-lineage-context-menu').hide().empty();
+
+ // prevents the drag event when something other than the
+ // left button is clicked
+ if (d3.event.button !== 0) {
+ d3.event.stopPropagation();
+ }
+ }, true)
+ .on('mouseover', function (d) {
+ links.filter(function (linkDatum) {
+ return d.id === linkDatum.flowFileUuid;
})
- .on('mouseout', function (d) {
- links.filter(function (linkDatum) {
- return d.id === linkDatum.flowFileUuid;
- }).classed('selected', false)
- .attr('marker-end', function (d) {
- return 'url(#' + d.target.type + ')';
- });
- });
+ .classed('selected', true)
+ .attr('marker-end', function (d) {
+ return 'url(#' + d.target.type + '-SELECTED)';
+ });
+ })
+ .on('mouseout', function (d) {
+ links.filter(function (linkDatum) {
+ return d.id === linkDatum.flowFileUuid;
+ }).classed('selected', false)
+ .attr('marker-end', function (d) {
+ return 'url(#' + d.target.type + ')';
+ });
+ });
var icon = flowfiles.append('g')
- .attr({
- 'class': 'flowfile-icon',
- 'transform': function (d) {
- return 'translate(-9,-9)';
- }
- });
+ .attr({
+ 'class': 'flowfile-icon',
+ 'transform': function (d) {
+ return 'translate(-9,-9)';
+ }
+ });
// flowfile icon
icon.append('path')
- .attr({
- 'd': function (d) {
- return 'M0, 2 l8, 0 l0, 8 l8, 0 l0, 8 l-16, 0 z';
- },
- 'class': 'flowfile-icon-base',
- 'stroke-width': 0,
- 'fill': '#93b2b1'
- });
+ .attr({
+ 'd': function (d) {
+ return 'M0, 2 l8, 0 l0, 8 l8, 0 l0, 8 l-16, 0 z';
+ },
+ 'class': 'flowfile-icon-base',
+ 'stroke-width': 0,
+ 'fill': '#93b2b1'
+ });
icon.append('path')
- .attr({
- 'd': function (d) {
- return 'M2, 18 a15, 15 0 0 0 13, -8 l1, 0 l0, 8 z';
- },
- 'class': 'flowfile-icon-arc',
- 'stroke': '#69878a',
- 'stroke-width': .5,
- 'fill': '#69878a'
- });
+ .attr({
+ 'd': function (d) {
+ return 'M2, 18 a15, 15 0 0 0 13, -8 l1, 0 l0, 8 z';
+ },
+ 'class': 'flowfile-icon-arc',
+ 'stroke': '#69878a',
+ 'stroke-width': .5,
+ 'fill': '#69878a'
+ });
icon.append('path')
- .attr({
- 'd': function (d) {
- return 'M0, 2 l8, 0 l0, 8 l8, 0 l0, 8 l-16, 0 z';
- },
- 'class': 'flowfile-icon-base-outline',
- 'stroke': '#4f6769',
- 'stroke-width': .5,
- 'fill': 'none'
- });
+ .attr({
+ 'd': function (d) {
+ return 'M0, 2 l8, 0 l0, 8 l8, 0 l0, 8 l-16, 0 z';
+ },
+ 'class': 'flowfile-icon-base-outline',
+ 'stroke': '#4f6769',
+ 'stroke-width': .5,
+ 'fill': 'none'
+ });
icon.append('path')
- .attr({
- 'd': function (d) {
- return 'M9, 1 l4, 0 l0, 4 l4, 0 l0, 4 l-8, 0 z';
- },
- 'class': 'flowfile-icon-mid',
- 'stroke-width': 0,
- 'fill': '#d2e0e5'
- });
+ .attr({
+ 'd': function (d) {
+ return 'M9, 1 l4, 0 l0, 4 l4, 0 l0, 4 l-8, 0 z';
+ },
+ 'class': 'flowfile-icon-mid',
+ 'stroke-width': 0,
+ 'fill': '#d2e0e5'
+ });
icon.append('path')
- .attr({
- 'd': function (d) {
- return 'M15, 9 a15, 15 0 0 0 1, -4 l1, 0 l0, 4 z';
- },
- 'class': 'flowfile-icon-arc',
- 'stroke': '#69878a',
- 'stroke-width': .5,
- 'fill': '#69878a'
- });
+ .attr({
+ 'd': function (d) {
+ return 'M15, 9 a15, 15 0 0 0 1, -4 l1, 0 l0, 4 z';
+ },
+ 'class': 'flowfile-icon-arc',
+ 'stroke': '#69878a',
+ 'stroke-width': .5,
+ 'fill': '#69878a'
+ });
icon.append('path')
- .attr({
- 'd': function (d) {
- return 'M9, 1 l4, 0 l0, 4 l4, 0 l0, 4 l-8, 0 z';
- },
- 'class': 'flowfile-icon-mid-outline',
- 'stroke': '#4f6769',
- 'stroke-width': .5,
- 'fill': 'none'
- });
+ .attr({
+ 'd': function (d) {
+ return 'M9, 1 l4, 0 l0, 4 l4, 0 l0, 4 l-8, 0 z';
+ },
+ 'class': 'flowfile-icon-mid-outline',
+ 'stroke': '#4f6769',
+ 'stroke-width': .5,
+ 'fill': 'none'
+ });
icon.append('path')
- .attr({
- 'd': function (d) {
- return 'M14, 0 l4, 0 l0, 4 l-4, 0 z';
- },
- 'class': 'flowfile-icon-top',
- 'stroke': '#4f6769',
- 'stroke-width': .5,
- 'fill': '#fff'
- });
+ .attr({
+ 'd': function (d) {
+ return 'M14, 0 l4, 0 l0, 4 l-4, 0 z';
+ },
+ 'class': 'flowfile-icon-top',
+ 'stroke': '#4f6769',
+ 'stroke-width': .5,
+ 'fill': '#fff'
+ });
};
// renders event nodes
var renderEvent = function (events) {
events
- .classed('event', true)
- .append('circle')
- .classed('selected', function (d) {
- return d.id === eventId;
- })
- .attr({
- 'r': 8,
- 'fill': '#527991',
- 'stroke': '#000',
- 'stroke-width': 1.0,
- 'id': function (d) {
- return 'event-node-' + d.id;
+ .classed('event', true)
+ .append('circle')
+ .classed('selected', function (d) {
+ return d.id === eventId;
+ })
+ .attr({
+ 'r': 8,
+ 'fill': '#527991',
+ 'stroke': '#000',
+ 'stroke-width': 1.0,
+ 'id': function (d) {
+ return 'event-node-' + d.id;
+ }
+ })
+ .on('contextmenu', function (d) {
+ // select the current node for a visible cue
+ d3.select(this).classed('context', true);
+
+ // empty an previous contents - in case they right click
on the
+ // node twice without closing the previous context menu
+ $('#provenance-lineage-context-menu').hide().empty();
+
+ var menuItems = [{
+ 'class': 'lineage-view-event',
+ 'text': 'View details',
+ 'click': function () {
+ showEventDetails(d.id, clusterNodeId);
}
- })
- .on('contextmenu', function (d) {
- // select the current node for a visible cue
- d3.select(this).classed('context', true);
-
- // empty an previous contents - in case they right
click on the
- // node twice without closing the previous context menu
- $('#provenance-lineage-context-menu').hide().empty();
-
- var menuItems = [{
- 'class': 'lineage-view-event',
- 'text': 'View details',
- 'click': function () {
- showEventDetails(d.id, clusterNodeId);
- }
- }];
-
- // if this is a spawn event show appropriate actions
- if (d.eventType === 'SPAWN' || d.eventType === 'CLONE'
|| d.eventType === 'FORK' || d.eventType === 'JOIN' || d.eventType ===
'REPLAY') {
- // starts the lineage expansion process
- var expandLineage = function (lineageRequest) {
- var lineageProgress =
$('#lineage-percent-complete');
-
- // add support to cancel outstanding requests
- when the button is pressed we
- // could be in one of two stages, 1) waiting
to GET the status or 2)
- // in the process of GETting the status.
Handle both cases by cancelling
- // the setTimeout (1) and by setting a flag to
indicate that a request has
- // been request so we can ignore the results
(2).
-
- var cancelled = false;
- var lineage = null;
- var lineageTimer = null;
-
- // update the progress bar value
-
nf.ProvenanceTable.updateProgress(lineageProgress, 0);
-
- // show the 'searching...' dialog
-
$('#lineage-query-dialog').modal('setButtonModel', [{
- buttonText: 'Cancel',
- handler: {
- click: function () {
- cancelled = true;
-
- // we are waiting for the next
poll attempt
- if (lineageTimer !== null) {
- // cancel it
- clearTimeout(lineageTimer);
-
- // cancel the provenance
- closeDialog();
- }
- }
+ }];
+
+ // if this is a spawn event show appropriate actions
+ if (d.eventType === 'SPAWN' || d.eventType === 'CLONE' ||
d.eventType === 'FORK' || d.eventType === 'JOIN' || d.eventType === 'REPLAY') {
+ // starts the lineage expansion process
+ var expandLineage = function (lineageRequest) {
+ var lineageProgress =
$('#lineage-percent-complete');
+
+ // add support to cancel outstanding requests -
when the button is pressed we
+ // could be in one of two stages, 1) waiting to
GET the status or 2)
+ // in the process of GETting the status. Handle
both cases by cancelling
+ // the setTimeout (1) and by setting a flag to
indicate that a request has
+ // been request so we can ignore the results (2).
+
+ var cancelled = false;
+ var lineage = null;
+ var lineageTimer = null;
+
+ // update the progress bar value
+ nf.ProvenanceTable.updateProgress(lineageProgress,
0);
+
+ // show the 'searching...' dialog
+ $('#lineage-query-dialog').modal('setButtonModel',
[{
+ buttonText: 'Cancel',
+ color: {
+ base: '#E3E8EB',
+ hover: '#C7D2D7',
+ text: '#004849'
+ },
+ handler: {
+ click: function () {
+ cancelled = true;
+
+ // we are waiting for the next poll
attempt
+ if (lineageTimer !== null) {
+ // cancel it
+ clearTimeout(lineageTimer);
+
+ // cancel the provenance
+ closeDialog();
}
- }]).modal('show');
+ }
+ }
+ }]).modal('show');
- // closes the searching dialog and cancels the
query on the server
- var closeDialog = function () {
- // cancel the provenance results since
we've successfully processed the results
- if
(nf.Common.isDefinedAndNotNull(lineage)) {
- cancelLineage(lineage);
- }
+ // closes the searching dialog and cancels the
query on the server
+ var closeDialog = function () {
+ // cancel the provenance results since we've
successfully processed the results
+ if (nf.Common.isDefinedAndNotNull(lineage)) {
+ cancelLineage(lineage);
+ }
- // close the dialog
- $('#lineage-query-dialog').modal('hide');
- };
+ // close the dialog
+ $('#lineage-query-dialog').modal('hide');
+ };
- // polls for the event lineage
- var pollLineage = function (nextDelay) {
- getLineage(lineage).done(function
(response) {
- lineage = response.lineage;
+ // polls for the event lineage
+ var pollLineage = function (nextDelay) {
+ getLineage(lineage).done(function (response) {
+ lineage = response.lineage;
- // process the lineage, if its not
done computing wait delay seconds before checking again
- processLineage(nextDelay);
- }).fail(closeDialog);
- };
+ // process the lineage, if its not done
computing wait delay seconds before checking again
+ processLineage(nextDelay);
+ }).fail(closeDialog);
+ };
- // processes the event lineage
- var processLineage = function (delay) {
- // if the request was cancelled just
ignore the current response
- if (cancelled === true) {
- closeDialog();
- return;
- }
+ // processes the event lineage
+ var processLineage = function (delay) {
+ // if the request was cancelled just ignore
the current response
+ if (cancelled === true) {
+ closeDialog();
+ return;
+ }
+
+ // close the dialog if the results contain an
error
+ if
(!nf.Common.isEmpty(lineage.results.errors)) {
+ var errors = lineage.results.errors;
+ nf.Dialog.showOkDialog({
+ headerText: 'Process Lineage',
+ dialogContent:
nf.Common.formatUnorderedList(errors)
+ });
+
+ closeDialog();
+ return;
+ }
- // close the dialog if the results contain
an error
- if
(!nf.Common.isEmpty(lineage.results.errors)) {
- var errors = lineage.results.errors;
+ // update the precent complete
+
nf.ProvenanceTable.updateProgress(lineageProgress, lineage.percentCompleted);
+
+ // process the results if they are finished
+ if (lineage.finished === true) {
+ var results = lineage.results;
+
+ // ensure the events haven't aged off
+ if (results.nodes.length > 0) {
+ // update the lineage graph
+ renderEventLineage(results);
+ } else {
+ // inform the user that no results
were found
nf.Dialog.showOkDialog({
- dialogContent:
nf.Common.formatUnorderedList(errors),
- overlayBackground: false
+ headerText: 'Lineage Results',
+ dialogContent: 'The lineage search
has completed successfully but there no results were found. The events may have
aged off.'
});
-
- closeDialog();
- return;
}
- // update the precent complete
-
nf.ProvenanceTable.updateProgress(lineageProgress, lineage.percentCompleted);
-
- // process the results if they are finished
- if (lineage.finished === true) {
- var results = lineage.results;
-
- // ensure the events haven't aged off
- if (results.nodes.length > 0) {
- // update the lineage graph
- renderEventLineage(results);
- } else {
- // inform the user that no results
were found
- nf.Dialog.showOkDialog({
- dialogContent: 'The lineage
search has completed successfully but there no results were found. The events
may have aged off.',
- overlayBackground: false
- });
- }
+ // close the searching.. dialog
+ closeDialog();
+ } else {
+ lineageTimer = setTimeout(function () {
+ // clear the timer since we've been
invoked
+ lineageTimer = null;
- // close the searching.. dialog
- closeDialog();
- } else {
- lineageTimer = setTimeout(function () {
- // clear the timer since we've
been invoked
- lineageTimer = null;
+ // calculate the next delay (back off)
+ var backoff = delay * 2;
+ var nextDelay = backoff >
nf.ProvenanceTable.MAX_DELAY ? nf.ProvenanceTable.MAX_DELAY : backoff;
- // calculate the next delay (back
off)
- var backoff = delay * 2;
- var nextDelay = backoff >
nf.ProvenanceTable.MAX_DELAY ? nf.ProvenanceTable.MAX_DELAY : backoff;
+ // for the lineage
+ pollLineage(nextDelay);
+ }, delay * 1000);
+ }
+ };
- // for the lineage
- pollLineage(nextDelay);
- }, delay * 1000);
+ // once the query is submitted wait until its
finished
+ submitLineage(lineageRequest).done(function
(response) {
+ lineage = response.lineage;
+
+ // process the lineage, if its not done
computing wait 1 second before checking again
+ processLineage(1);
+ }).fail(closeDialog);
+ };
+
+ // handles updating the lineage graph
+ var renderEventLineage = function (lineageResults) {
+ addLineage(lineageResults.nodes,
lineageResults.links);
+ };
+
+ // collapses the lineage for the specified event in
the specified direction
+ var collapseLineage = function (eventId) {
+ // get the event in question and collapse in the
appropriate direction
+ getEventDetails(eventId,
clusterNodeId).done(function (response) {
+ var provenanceEvent = response.provenanceEvent;
+ var eventUuid = provenanceEvent.flowFileUuid;
+ var eventUuids =
d3.set(provenanceEvent.childUuids);
+
+ // determines if the specified event should be
removable based on if the collapsing is fanning in/out
+ var allowEventRemoval = function (fanIn, node)
{
+ if (fanIn) {
+ return node.id !== eventId;
+ } else {
+ return node.flowFileUuid !== eventUuid
&& $.inArray(eventUuid, node.parentUuids) === -1;
}
};
- // once the query is submitted wait until its
finished
- submitLineage(lineageRequest).done(function
(response) {
- lineage = response.lineage;
+ // determines if the specified link should be
removable based on if the collapsing is fanning in/out
+ var allowLinkRemoval = function (fanIn, link) {
+ if (fanIn) {
+ return true;
+ } else {
+ return link.flowFileUuid !== eventUuid;
+ }
+ };
- // process the lineage, if its not done
computing wait 1 second before checking again
- processLineage(1);
- }).fail(closeDialog);
- };
+ // the event is fan in if the flowfile uuid is
in the children
+ var fanIn = $.inArray(eventUuid,
provenanceEvent.childUuids) >= 0;
- // handles updating the lineage graph
- var renderEventLineage = function (lineageResults)
{
- addLineage(lineageResults.nodes,
lineageResults.links);
- };
+ // collapses the specified uuids
+ var collapse = function (uuids) {
+ var newUuids = false;
- // collapses the lineage for the specified event
in the specified direction
- var collapseLineage = function (eventId) {
- // get the event in question and collapse in
the appropriate direction
- getEventDetails(eventId,
clusterNodeId).done(function (response) {
- var provenanceEvent =
response.provenanceEvent;
- var eventUuid =
provenanceEvent.flowFileUuid;
- var eventUuids =
d3.set(provenanceEvent.childUuids);
-
- // determines if the specified event
should be removable based on if the collapsing is fanning in/out
- var allowEventRemoval = function (fanIn,
node) {
- if (fanIn) {
- return node.id !== eventId;
- } else {
- return node.flowFileUuid !==
eventUuid && $.inArray(eventUuid, node.parentUuids) === -1;
- }
- };
-
- // determines if the specified link should
be removable based on if the collapsing is fanning in/out
- var allowLinkRemoval = function (fanIn,
link) {
- if (fanIn) {
- return true;
- } else {
- return link.flowFileUuid !==
eventUuid;
- }
- };
-
- // the event is fan in if the flowfile
uuid is in the children
- var fanIn = $.inArray(eventUuid,
provenanceEvent.childUuids) >= 0;
-
- // collapses the specified uuids
- var collapse = function (uuids) {
- var newUuids = false;
-
- // consider each node for being
collapsed
- $.each(nodeLookup.values(), function
(_, node) {
- // if this node is in the uuids
remove it unless its the original event or is part of this and another lineage
- if (uuids.has(node.flowFileUuid)
&& allowEventRemoval(fanIn, node)) {
- // remove it from the look
lookup
- nodeLookup.remove(node.id);
-
- // include all related
outgoing flow file uuids
- $.each(node.outgoing, function
(_, outgoing) {
- if
(!uuids.has(outgoing.flowFileUuid)) {
-
uuids.add(outgoing.flowFileUuid);
- newUuids = true;
- }
- });
- }
- });
+ // consider each node for being collapsed
+ $.each(nodeLookup.values(), function (_,
node) {
+ // if this node is in the uuids remove
it unless its the original event or is part of this and another lineage
+ if (uuids.has(node.flowFileUuid) &&
allowEventRemoval(fanIn, node)) {
+ // remove it from the look lookup
+ nodeLookup.remove(node.id);
- // update the link data
- $.each(linkLookup.values(), function
(_, link) {
- // if this link is in the uuids
remove it
- if (uuids.has(link.flowFileUuid)
&& allowLinkRemoval(fanIn, link)) {
- // remove it from the link
lookup
- linkLookup.remove(link.id);
-
- // add a related uuid that
needs to be collapse
- var next = link.target;
- if
(!uuids.has(next.flowFileUuid)) {
-
uuids.add(next.flowFileUuid);
+ // include all related outgoing
flow file uuids
+ $.each(node.outgoing, function (_,
outgoing) {
+ if
(!uuids.has(outgoing.flowFileUuid)) {
+
uuids.add(outgoing.flowFileUuid);
newUuids = true;
}
- }
- });
+ });
+ }
+ });
- // collapse any related uuids
- if (newUuids) {
- collapse(uuids);
+ // update the link data
+ $.each(linkLookup.values(), function (_,
link) {
+ // if this link is in the uuids remove
it
+ if (uuids.has(link.flowFileUuid) &&
allowLinkRemoval(fanIn, link)) {
+ // remove it from the link lookup
+ linkLookup.remove(link.id);
+
+ // add a related uuid that needs
to be collapse
+ var next = link.target;
+ if (!uuids.has(next.flowFileUuid))
{
+ uuids.add(next.flowFileUuid);
+ newUuids = true;
+ }
}
- };
+ });
- // collapse the specified uuids
- collapse(eventUuids);
+ // collapse any related uuids
+ if (newUuids) {
+ collapse(uuids);
+ }
+ };
- // update the layout
- refresh();
- });
- };
+ // collapse the specified uuids
+ collapse(eventUuids);
- // add menu items
- menuItems.push({
- 'class': 'lineage-view-parents',
- 'text': 'Find parents',
- 'click': function () {
- expandLineage({
- lineageRequestType: 'PARENTS',
- eventId: d.id,
- clusterNodeId: clusterNodeId
- });
- }
- }, {
- 'class': 'lineage-view-children',
- 'text': 'Expand',
- 'click': function () {
- expandLineage({
- lineageRequestType: 'CHILDREN',
- eventId: d.id,
- clusterNodeId: clusterNodeId
- });
- }
- }, {
- 'class': 'lineage-collapse-children',
- 'text': 'Collapse',
- 'click': function () {
- // collapse the children lineage
- collapseLineage(d.id);
- }
+ // update the layout
+ refresh();
});
- }
+ };
+
+ // add menu items
+ menuItems.push({
+ 'class': 'lineage-view-parents',
+ 'text': 'Find parents',
+ 'click': function () {
+ expandLineage({
+ lineageRequestType: 'PARENTS',
+ eventId: d.id,
+ clusterNodeId: clusterNodeId
+ });
+ }
+ }, {
+ 'class': 'lineage-view-children',
+ 'text': 'Expand',
+ 'click': function () {
+ expandLineage({
+ lineageRequestType: 'CHILDREN',
+ eventId: d.id,
+ clusterNodeId: clusterNodeId
+ });
+ }
+ }, {
+ 'class': 'lineage-collapse-children',
+ 'text': 'Collapse',
+ 'click': function () {
+ // collapse the children lineage
+ collapseLineage(d.id);
+ }
+ });
+ }
- // show the context menu for an event
- addContextMenuItems(menuItems);
- });
+ // show the context menu for an event
+ addContextMenuItems(menuItems);
+ });
events
- .append('text')
- .attr({
- 'id': function (d) {
- return 'event-text-' + d.id;
- },
- 'class': 'event-type'
- })
- .classed('expand-parents', function (d) {
- return d.eventType === 'SPAWN';
- })
- .classed('expand-children', function (d) {
- return d.eventType === 'SPAWN';
- })
- .each(function (d) {
- var label = d3.select(this);
- if (d.eventType === 'CONTENT_MODIFIED' || d.eventType
=== 'ATTRIBUTES_MODIFIED') {
- var lines = [];
- if (d.eventType === 'CONTENT_MODIFIED') {
- lines.push('CONTENT');
- } else {
- lines.push('ATTRIBUTES');
- }
- lines.push('MODIFIED');
-
- // append each line
- $.each(lines, function (i, line) {
- label.append('tspan')
- .attr('x', '0')
- .attr('dy', '1.2em')
- .text(function () {
- return line;
- });
- });
- label.attr('transform', 'translate(10,-14)');
+ .append('text')
+ .attr({
+ 'id': function (d) {
+ return 'event-text-' + d.id;
+ },
+ 'class': 'event-type'
+ })
+ .classed('expand-parents', function (d) {
+ return d.eventType === 'SPAWN';
+ })
+ .classed('expand-children', function (d) {
+ return d.eventType === 'SPAWN';
+ })
+ .each(function (d) {
+ var label = d3.select(this);
+ if (d.eventType === 'CONTENT_MODIFIED' || d.eventType ===
'ATTRIBUTES_MODIFIED') {
+ var lines = [];
+ if (d.eventType === 'CONTENT_MODIFIED') {
+ lines.push('CONTENT');
} else {
- label.text(d.eventType).attr({
- 'x': 10,
- 'y': 4
- });
+ lines.push('ATTRIBUTES');
}
- });
+ lines.push('MODIFIED');
+
+ // append each line
+ $.each(lines, function (i, line) {
+ label.append('tspan')
+ .attr('x', '0')
+ .attr('dy', '1.2em')
+ .text(function () {
+ return line;
+ });
+ });
+ label.attr('transform', 'translate(10,-14)');
+ } else {
+ label.text(d.eventType).attr({
+ 'x': 10,
+ 'y': 4
+ });
+ }
+ });
};
// updates the ui
@@ -1129,19 +1133,19 @@ nf.ProvenanceLineage = (function () {
// add new nodes
var nodesEntered = nodes.enter()
- .append('g')
- .attr('id', function (d) {
- return 'lineage-group-' + d.id;
- })
- .classed('node', true)
- .attr('transform', function (d) {
- if (d.incoming.length === 0) {
- return 'translate(' + (width / 2) + ',50)';
- } else {
- return 'translate(' + d.incoming[0].source.x + ','
+ d.incoming[0].source.y + ')';
- }
- })
- .style('opacity', 0);
+ .append('g')
+ .attr('id', function (d) {
+ return 'lineage-group-' + d.id;
+ })
+ .classed('node', true)
+ .attr('transform', function (d) {
+ if (d.incoming.length === 0) {
+ return 'translate(' + (width / 2) + ',50)';
+ } else {
+ return 'translate(' + d.incoming[0].source.x + ',' +
d.incoming[0].source.y + ')';
+ }
+ })
+ .style('opacity', 0);
// treat flowfiles and events differently
nodesEntered.filter(function (d) {
@@ -1153,27 +1157,27 @@ nf.ProvenanceLineage = (function () {
// update the nodes
nodes
- .transition()
- .duration(400)
- .attr('transform', function (d) {
- return 'translate(' + d.x + ', ' + d.y + ')';
- })
- .style('opacity', 1);
+ .transition()
+ .duration(400)
+ .attr('transform', function (d) {
+ return 'translate(' + d.x + ', ' + d.y + ')';
+ })
+ .style('opacity', 1);
// remove old nodes
nodes.exit()
- .transition()
- .delay(200)
- .duration(400)
- .attr('transform', function (d) {
- if (d.incoming.length === 0) {
- return 'translate(' + (width / 2) + ',50)';
- } else {
- return 'translate(' + d.incoming[0].source.x + ','
+ d.incoming[0].source.y + ')';
- }
- })
- .style('opacity', 0)
- .remove();
+ .transition()
+ .delay(200)
+ .duration(400)
+ .attr('transform', function (d) {
+ if (d.incoming.length === 0) {
+ return 'translate(' + (width / 2) + ',50)';
+ } else {
+ return 'translate(' + d.incoming[0].source.x + ',' +
d.incoming[0].source.y + ')';
+ }
+ })
+ .style('opacity', 0)
+ .remove();
// update the link data
links = links.data(linkLookup.values(), function (d) {
@@ -1182,44 +1186,44 @@ nf.ProvenanceLineage = (function () {
// add new links
links.enter()
- .insert('path', '.node')
- .attr({
- 'class': 'link',
- 'stroke-width': 1.5,
- 'stroke': '#000',
- 'fill': 'none',
- 'd': function (d) {
- return 'M' + d.source.x + ',' + d.source.y + 'L' +
d.source.x + ',' + d.source.y;
- }
- })
- .style('opacity', 0);
+ .insert('path', '.node')
+ .attr({
+ 'class': 'link',
+ 'stroke-width': 1.5,
+ 'stroke': '#000',
+ 'fill': 'none',
+ 'd': function (d) {
+ return 'M' + d.source.x + ',' + d.source.y + 'L' +
d.source.x + ',' + d.source.y;
+ }
+ })
+ .style('opacity', 0);
// update the links
links
- .attr('marker-end', '')
- .transition()
- .delay(200)
- .duration(400)
- .attr({
- 'marker-end': function (d) {
- return 'url(#' + d.target.type + ')';
- },
- 'd': function (d) {
- return 'M' + d.source.x + ',' + d.source.y + 'L' +
d.target.x + ',' + d.target.y;
- }
- })
- .style('opacity', 1);
+ .attr('marker-end', '')
+ .transition()
+ .delay(200)
+ .duration(400)
+ .attr({
+ 'marker-end': function (d) {
+ return 'url(#' + d.target.type + ')';
+ },
+ 'd': function (d) {
+ return 'M' + d.source.x + ',' + d.source.y + 'L' +
d.target.x + ',' + d.target.y;
+ }
+ })
+ .style('opacity', 1);
// remove old links
links.exit()
- .attr('marker-end', '')
- .transition()
- .duration(400)
- .attr('d', function (d) {
- return 'M' + d.source.x + ',' + d.source.y + 'L' +
d.source.x + ',' + d.source.y;
- })
- .style('opacity', 0)
- .remove();
+ .attr('marker-end', '')
+ .transition()
+ .duration(400)
+ .attr('d', function (d) {
+ return 'M' + d.source.x + ',' + d.source.y + 'L' +
d.source.x + ',' + d.source.y;
+ })
+ .style('opacity', 0)
+ .remove();
};
// show the lineage pane and hide the event search results
@@ -1229,7 +1233,7 @@ nf.ProvenanceLineage = (function () {
// add the initial lineage
addLineage(lineageResults.nodes, lineageResults.links);
};
-
+
return {
/**
* Initializes the lineage graph.
@@ -1310,10 +1314,10 @@ nf.ProvenanceLineage = (function () {
initLineageQueryDialog();
},
-
+
/**
* Shows the lineage for the specified flowfile uuid.
- *
+ *
* @param {string} flowFileUuid The flowfile uuid
* @param {integer} eventId The id of the event
* @param {string} clusterNodeId The id of the node in the cluster
where this event/flowfile originated
@@ -1343,22 +1347,27 @@ nf.ProvenanceLineage = (function () {
// show the 'searching...' dialog
$('#lineage-query-dialog').modal('setButtonModel', [{
- buttonText: 'Cancel',
- handler: {
- click: function () {
- cancelled = true;
-
- // we are waiting for the next poll attempt
- if (lineageTimer !== null) {
- // cancel it
- clearTimeout(lineageTimer);
-
- // cancel the provenance
- closeDialog();
- }
+ buttonText: 'Cancel',
+ color: {
+ base: '#E3E8EB',
+ hover: '#C7D2D7',
+ text: '#004849'
+ },
+ handler: {
+ click: function () {
+ cancelled = true;
+
+ // we are waiting for the next poll attempt
+ if (lineageTimer !== null) {
+ // cancel it
+ clearTimeout(lineageTimer);
+
+ // cancel the provenance
+ closeDialog();
}
}
- }]).modal('show');
+ }
+ }]).modal('show');
// closes the searching dialog and cancels the query on the server
var closeDialog = function () {
@@ -1393,8 +1402,8 @@ nf.ProvenanceLineage = (function () {
if (!nf.Common.isEmpty(lineage.results.errors)) {
var errors = lineage.results.errors;
nf.Dialog.showOkDialog({
- dialogContent: nf.Common.formatUnorderedList(errors),
- overlayBackground: false
+ headerText: 'Process Lineage',
+ dialogContent: nf.Common.formatUnorderedList(errors)
});
closeDialog();