mirror of https://github.com/apache/nifi.git
NIFI-4481:
- Adding support for visualizing if a component is scheduled for primary node only. This closes #2210.
This commit is contained in:
parent
b8a3862078
commit
53e63eaf7c
|
@ -16,6 +16,8 @@
|
|||
*/
|
||||
package org.apache.nifi.controller.status;
|
||||
|
||||
import org.apache.nifi.scheduling.ExecutionNode;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
@ -29,6 +31,7 @@ public class ProcessorStatus implements Cloneable {
|
|||
private String name;
|
||||
private String type;
|
||||
private RunStatus runStatus;
|
||||
private ExecutionNode executionNode;
|
||||
private int inputCount;
|
||||
private long inputBytes;
|
||||
private int outputCount;
|
||||
|
@ -90,6 +93,14 @@ public class ProcessorStatus implements Cloneable {
|
|||
this.runStatus = runStatus;
|
||||
}
|
||||
|
||||
public ExecutionNode getExecutionNode() {
|
||||
return executionNode;
|
||||
}
|
||||
|
||||
public void setExecutionNode(ExecutionNode executionNode) {
|
||||
this.executionNode = executionNode;
|
||||
}
|
||||
|
||||
public void setInputCount(final int inputCount) {
|
||||
this.inputCount = inputCount;
|
||||
}
|
||||
|
@ -244,6 +255,7 @@ public class ProcessorStatus implements Cloneable {
|
|||
clonedObj.averageLineageDuration = averageLineageDuration;
|
||||
clonedObj.flowFilesRemoved = flowFilesRemoved;
|
||||
clonedObj.runStatus = runStatus;
|
||||
clonedObj.executionNode = executionNode;
|
||||
clonedObj.type = type;
|
||||
clonedObj.counters = counters == null ? null : new HashMap<>(counters);
|
||||
return clonedObj;
|
||||
|
@ -262,6 +274,8 @@ public class ProcessorStatus implements Cloneable {
|
|||
builder.append(type);
|
||||
builder.append(", runStatus=");
|
||||
builder.append(runStatus);
|
||||
builder.append(", executionNode=");
|
||||
builder.append(executionNode);
|
||||
builder.append(", inputCount=");
|
||||
builder.append(inputCount);
|
||||
builder.append(", inputBytes=");
|
||||
|
|
|
@ -31,6 +31,7 @@ public class ProcessorStatusSnapshotDTO implements Cloneable {
|
|||
private String name;
|
||||
private String type;
|
||||
private String runStatus;
|
||||
private String executionNode;
|
||||
|
||||
private Long bytesRead = 0L;
|
||||
private Long bytesWritten = 0L;
|
||||
|
@ -103,6 +104,18 @@ public class ProcessorStatusSnapshotDTO implements Cloneable {
|
|||
this.runStatus = runStatus;
|
||||
}
|
||||
|
||||
@ApiModelProperty(
|
||||
value = "Indicates the node where the process will execute.",
|
||||
allowableValues = "ALL, PRIMARY"
|
||||
)
|
||||
public String getExecutionNode() {
|
||||
return executionNode;
|
||||
}
|
||||
|
||||
public void setExecutionNode(String executionNode) {
|
||||
this.executionNode = executionNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The total count and size of flow files that have been accepted in the last five minutes
|
||||
*/
|
||||
|
@ -280,6 +293,7 @@ public class ProcessorStatusSnapshotDTO implements Cloneable {
|
|||
other.setType(getType());
|
||||
|
||||
other.setRunStatus(getRunStatus());
|
||||
other.setExecutionNode(getExecutionNode());
|
||||
other.setBytesRead(getBytesRead());
|
||||
other.setBytesWritten(getBytesWritten());
|
||||
other.setFlowFilesIn(getFlowFilesIn());
|
||||
|
|
|
@ -2976,6 +2976,7 @@ public class FlowController implements EventAccess, ControllerServiceProvider, R
|
|||
status.setRunStatus(RunStatus.Stopped);
|
||||
}
|
||||
|
||||
status.setExecutionNode(procNode.getExecutionNode());
|
||||
status.setActiveThreadCount(processScheduler.getActiveThreadCount(procNode));
|
||||
|
||||
return status;
|
||||
|
|
|
@ -1106,6 +1106,7 @@ public final class DtoFactory {
|
|||
|
||||
// determine the run status
|
||||
snapshot.setRunStatus(procStatus.getRunStatus().toString());
|
||||
snapshot.setExecutionNode(procStatus.getExecutionNode().toString());
|
||||
|
||||
snapshot.setActiveThreadCount(procStatus.getActiveThreadCount());
|
||||
snapshot.setType(procStatus.getType());
|
||||
|
|
|
@ -66,7 +66,6 @@ g.component rect.body.unauthorized {
|
|||
fill: #f4f6f7;
|
||||
}
|
||||
|
||||
|
||||
g.component rect.border {
|
||||
stroke: rgba(0,0,0,0.25);
|
||||
stroke-width: 1;
|
||||
|
@ -187,7 +186,7 @@ text.processor-icon {
|
|||
font-size: 30px;
|
||||
}
|
||||
|
||||
circle.restricted-background {
|
||||
circle.restricted-background, circle.is-primary-background {
|
||||
visibility: hidden;
|
||||
fill: rgba(255, 255, 255, 0.90);
|
||||
}
|
||||
|
@ -199,6 +198,12 @@ text.restricted {
|
|||
fill: #ba554a;
|
||||
}
|
||||
|
||||
text.is-primary {
|
||||
visibility: hidden;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
text.run-status-icon {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
|
|
@ -103,6 +103,23 @@ input.search-nodes {
|
|||
color: #888;
|
||||
}
|
||||
|
||||
div.is-primary-icon {
|
||||
color: #000;
|
||||
font-family: Roboto;
|
||||
font-size: 10px;
|
||||
font-weight: bold;
|
||||
line-height: 14px;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
background-color: rgba(255, 255, 255, 0.9);
|
||||
border: 1px solid #aaa;
|
||||
border-radius: 7px;
|
||||
margin-right: 3px;
|
||||
margin-top: 3px;
|
||||
float: left;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* system diagnostics dialog */
|
||||
|
||||
#system-diagnostics-refresh-container{
|
||||
|
|
|
@ -23,9 +23,10 @@
|
|||
'd3',
|
||||
'nf.Common',
|
||||
'nf.Client',
|
||||
'nf.ClusterSummary',
|
||||
'nf.CanvasUtils'],
|
||||
function ($, d3, nfCommon, nfClient, nfCanvasUtils) {
|
||||
return (nf.Processor = factory($, d3, nfCommon, nfClient, nfCanvasUtils));
|
||||
function ($, d3, nfCommon, nfClient, nfClusterSummary, nfCanvasUtils) {
|
||||
return (nf.Processor = factory($, d3, nfCommon, nfClient, nfClusterSummary, nfCanvasUtils));
|
||||
});
|
||||
} else if (typeof exports === 'object' && typeof module === 'object') {
|
||||
module.exports = (nf.Processor =
|
||||
|
@ -33,15 +34,17 @@
|
|||
require('d3'),
|
||||
require('nf.Common'),
|
||||
require('nf.Client'),
|
||||
require('nf.ClusterSummary'),
|
||||
require('nf.CanvasUtils')));
|
||||
} else {
|
||||
nf.Processor = factory(root.$,
|
||||
root.d3,
|
||||
root.nf.Common,
|
||||
root.nf.Client,
|
||||
root.nf.ClusterSummary,
|
||||
root.nf.CanvasUtils);
|
||||
}
|
||||
}(this, function ($, d3, nfCommon, nfClient, nfCanvasUtils) {
|
||||
}(this, function ($, d3, nfCommon, nfClient, nfClusterSummary, nfCanvasUtils) {
|
||||
'use strict';
|
||||
|
||||
var nfConnectable;
|
||||
|
@ -181,6 +184,27 @@
|
|||
})
|
||||
.text('\uf132');
|
||||
|
||||
// is primary icon background
|
||||
processor.append('circle')
|
||||
.attr({
|
||||
'r': 9,
|
||||
'cx': 38,
|
||||
'cy': 36,
|
||||
'class': 'is-primary-background'
|
||||
});
|
||||
|
||||
// is primary icon
|
||||
processor.append('text')
|
||||
.attr({
|
||||
'x': 34.75,
|
||||
'y': 40,
|
||||
'class': 'is-primary'
|
||||
})
|
||||
.text('P')
|
||||
.append('title').text(function (d) {
|
||||
return 'This component is only scheduled to execute on the Primary Node';
|
||||
});
|
||||
|
||||
// make processors selectable
|
||||
processor.call(nfSelectable.activate).call(nfContextMenu.activate).call(nfQuickSelect.activate);
|
||||
};
|
||||
|
@ -686,11 +710,15 @@
|
|||
// restricted component indicator
|
||||
processor.select('circle.restricted-background').style('visibility', showRestricted);
|
||||
processor.select('text.restricted').style('visibility', showRestricted);
|
||||
|
||||
// is primary component indicator
|
||||
processor.select('circle.is-primary-background').style('visibility', showIsPrimary);
|
||||
processor.select('text.is-primary').style('visibility', showIsPrimary);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns whether the resticted indicator should be shown for a given
|
||||
* Returns whether the resticted indicator should be shown for a given component
|
||||
* @param d
|
||||
* @returns {*}
|
||||
*/
|
||||
|
@ -700,7 +728,16 @@
|
|||
}
|
||||
|
||||
return d.component.restricted ? 'visible' : 'hidden';
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns whether the is primary indicator should be shown for a given component
|
||||
* @param d
|
||||
* @returns {*}
|
||||
*/
|
||||
var showIsPrimary = function (d) {
|
||||
return nfClusterSummary.isClustered() && d.status.aggregateSnapshot.executionNode === 'PRIMARY' ? 'visible' : 'hidden';
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates the stats for the processors in the specified selection.
|
||||
|
|
|
@ -276,6 +276,19 @@
|
|||
return markup;
|
||||
};
|
||||
|
||||
// formatter for name
|
||||
var nameFormatter = function (row, cell, value, columnDef, dataContext) {
|
||||
var markup = '';
|
||||
|
||||
if (isClustered && dataContext.executionNode === 'PRIMARY') {
|
||||
markup += '<div class="is-primary-icon" title="This component is only scheduled to execute on the Primary Node">P</div>';
|
||||
}
|
||||
|
||||
markup += nfCommon.escapeHtml(value);
|
||||
|
||||
return markup;
|
||||
};
|
||||
|
||||
// formatter for io
|
||||
var ioFormatter = function (row, cell, value, columnDef, dataContext) {
|
||||
return nfCommon.escapeHtml(dataContext.read) + ' / ' + nfCommon.escapeHtml(dataContext.written);
|
||||
|
@ -326,9 +339,9 @@
|
|||
id: 'name',
|
||||
field: 'name',
|
||||
name: 'Name',
|
||||
formatter: nameFormatter,
|
||||
sortable: true,
|
||||
resizable: true,
|
||||
formatter: nfCommon.genericValueFormatter
|
||||
resizable: true
|
||||
};
|
||||
var runStatusColumn = {
|
||||
id: 'runStatus',
|
||||
|
|
Loading…
Reference in New Issue