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 2018/10/11 15:40:16 UTC

nifi git commit: NIFI-5661: Adding Load Balance config UI Incorporated review comments. Move combo options to a common place.

Repository: nifi
Updated Branches:
  refs/heads/master a6f722222 -> 8a751e801


NIFI-5661: Adding Load Balance config UI
Incorporated review comments.
Move combo options to a common place.

This closes #3046


Project: http://git-wip-us.apache.org/repos/asf/nifi/repo
Commit: http://git-wip-us.apache.org/repos/asf/nifi/commit/8a751e80
Tree: http://git-wip-us.apache.org/repos/asf/nifi/tree/8a751e80
Diff: http://git-wip-us.apache.org/repos/asf/nifi/diff/8a751e80

Branch: refs/heads/master
Commit: 8a751e80183d46febd7abc6e66b72342ca5a5f38
Parents: a6f7222
Author: Koji Kawamura <ij...@apache.org>
Authored: Fri Sep 14 21:18:04 2018 +0900
Committer: Matt Gilman <ma...@gmail.com>
Committed: Thu Oct 11 11:36:28 2018 -0400

----------------------------------------------------------------------
 .../canvas/connection-configuration.jsp         | 59 +++++++++++----
 .../WEB-INF/partials/connection-details.jsp     | 67 ++++++++++++-----
 .../src/main/webapp/css/connection-details.css  | 16 ++++-
 .../nifi-web-ui/src/main/webapp/css/graph.css   | 16 ++++-
 .../js/nf/canvas/nf-connection-configuration.js | 62 ++++++++++++++--
 .../main/webapp/js/nf/canvas/nf-connection.js   | 76 ++++++++++++++++++--
 .../src/main/webapp/js/nf/nf-common.js          | 51 +++++++++++++
 .../main/webapp/js/nf/nf-connection-details.js  | 40 +++++++++--
 8 files changed, 341 insertions(+), 46 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi/blob/8a751e80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/connection-configuration.jsp
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/connection-configuration.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/connection-configuration.jsp
index 9e65743..fee7da7 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/connection-configuration.jsp
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/canvas/connection-configuration.jsp
@@ -42,22 +42,57 @@
                             <input type="text" id="flow-file-expiration" name="flow-file-expiration" class="setting-input"/>
                         </div>
                     </div>
-                    <div class="setting">
-                        <div class="setting-name">
-                            Back pressure object threshold
-                            <div class="fa fa-question-circle" alt="Info" title="The maximum number of objects that can be queued before back pressure is applied."></div>
+                    <div class="multi-column-settings">
+                        <div class="setting">
+                            <div class="setting-name">
+                                Back Pressure<br/>Object threshold
+                                <div class="fa fa-question-circle" alt="Info" title="The maximum number of objects that can be queued before back pressure is applied."></div>
+                            </div>
+                            <div class="setting-field">
+                                <input type="text" id="back-pressure-object-threshold" name="back-pressure-object-threshold" class="setting-input"/>
+                            </div>
                         </div>
-                        <div class="setting-field">
-                            <input type="text" id="back-pressure-object-threshold" name="back-pressure-object-threshold" class="setting-input"/>
+                        <div class="separator">&nbsp;</div>
+                        <div class="setting">
+                            <div class="setting-name">
+                                &nbsp;<br/>Size threshold
+                                <div class="fa fa-question-circle" alt="Info" title="The maximum data size of objects that can be queued before back pressure is applied."></div>
+                            </div>
+                            <div class="setting-field">
+                                <input type="text" id="back-pressure-data-size-threshold" name="back-pressure-data-size-threshold" class="setting-input"/>
+                            </div>
                         </div>
                     </div>
-                    <div class="setting">
-                        <div class="setting-name">
-                            Back pressure data size threshold
-                            <div class="fa fa-question-circle" alt="Info" title="The maximum data size of objects that can be queued before back pressure is applied."></div>
+                    <div id="load-balance-settings">
+                        <div class="multi-column-settings">
+                            <div class="setting">
+                                <div class="setting-name">
+                                    Load Balance Strategy
+                                    <div class="fa fa-question-circle" alt="Info" title="How to load balance the data in this Connection across the nodes in the cluster."></div>
+                                </div>
+                                <div class="setting-field">
+                                    <div id="load-balance-strategy-combo"></div>
+                                </div>
+                            </div>
+                            <div id="load-balance-partition-attribute-setting-separator" class="separator">&nbsp;</div>
+                            <div id="load-balance-partition-attribute-setting" class="setting">
+                                <div class="setting-name">
+                                    Attribute Name
+                                    <div class="fa fa-question-circle" alt="Info" title="The FlowFile Attribute to use for determining which node a FlowFile will go to."></div>
+                                </div>
+                                <div class="setting-field">
+                                    <input type="text" id="load-balance-partition-attribute" name="load-balance-partition-attribute" class="setting-input"/>
+                                </div>
+                            </div>
                         </div>
-                        <div class="setting-field">
-                            <input type="text" id="back-pressure-data-size-threshold" name="back-pressure-data-size-threshold" class="setting-input"/>
+                        <div id="load-balance-compression-setting" class="setting">
+                            <div class="setting-name">
+                                Load Balance Compression
+                                <div class="fa fa-question-circle" alt="Info" title="Whether or not data should be compressed when being transferred between nodes in the cluster."></div>
+                            </div>
+                            <div class="setting-field">
+                                <div id="load-balance-compression-combo"></div>
+                            </div>
                         </div>
                     </div>
                 </div>

http://git-wip-us.apache.org/repos/asf/nifi/blob/8a751e80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/connection-details.jsp
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/connection-details.jsp b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/connection-details.jsp
index f7637a2..8ce9684 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/connection-details.jsp
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/WEB-INF/partials/connection-details.jsp
@@ -83,25 +83,60 @@
                         </div>
                         <div class="clear"></div>
                     </div>
-                    <div class="setting">
-                        <div class="setting-name">
-                            Back pressure object threshold
-                            <div class="fa fa-question-circle" alt="Info" title="The maximum number of objects that can be queued before back pressure is applied."></div>
+                    <div class="multi-column-settings">
+                        <div class="setting">
+                            <div class="setting-name">
+                                Back Pressure<br/>Object threshold
+                                <div class="fa fa-question-circle" alt="Info" title="The maximum number of objects that can be queued before back pressure is applied."></div>
+                            </div>
+                            <div class="setting-field">
+                                <span id="read-only-back-pressure-object-threshold"></span>
+                            </div>
+                            <div class="clear"></div>
+                        </div>
+                        <div class="separator">&nbsp;</div>
+                        <div class="setting">
+                            <div class="setting-name">
+                                &nbsp;<br/>Size threshold
+                                <div class="fa fa-question-circle" alt="Info" title="The maximum data size of objects that can be queued before back pressure is applied."></div>
+                            </div>
+                            <div class="setting-field">
+                                <span id="read-only-back-pressure-data-size-threshold"></span>
+                            </div>
+                            <div class="clear"></div>
                         </div>
-                        <div class="setting-field">
-                            <span id="read-only-back-pressure-object-threshold"></span>
-                        </div>
-                        <div class="clear"></div>
                     </div>
-                    <div class="setting">
-                        <div class="setting-name">
-                            Back pressure data size threshold
-                            <div class="fa fa-question-circle" alt="Info" title="The maximum data size of objects that can be queued before back pressure is applied."></div>
+                    <div id="read-only-load-balance-settings">
+                        <div class="multi-column-settings">
+                            <div class="setting">
+                                <div class="setting-name">
+                                    Load Balance Strategy
+                                    <div class="fa fa-question-circle" alt="Info" title="How to load balance the data in this Connection across the nodes in the cluster."></div>
+                                </div>
+                                <div class="setting-field">
+                                    <div id="read-only-load-balance-strategy"></div>
+                                </div>
+                            </div>
+                            <div class="separator">&nbsp;</div>
+                            <div id="read-only-load-balance-partition-attribute-setting" class="setting">
+                                <div class="setting-name">
+                                    Attribute Name
+                                    <div class="fa fa-question-circle" alt="Info" title="The FlowFile Attribute to use for determining which node a FlowFile will go to."></div>
+                                </div>
+                                <div class="setting-field">
+                                    <span id="read-only-load-balance-partition-attribute"></span>
+                                </div>
+                            </div>
+                        </div>
+                        <div id="read-only-load-balance-compression-setting" class="setting">
+                            <div class="setting-name">
+                                Load Balance Compression
+                                <div class="fa fa-question-circle" alt="Info" title="Whether or not data should be compressed when being transferred between nodes in the cluster."></div>
+                            </div>
+                            <div class="setting-field">
+                                <div id="read-only-load-balance-compression"></div>
+                            </div>
                         </div>
-                        <div class="setting-field">
-                            <span id="read-only-back-pressure-data-size-threshold"></span>
-                        </div>
-                        <div class="clear"></div>
                     </div>
                 </div>
                 <div class="spacer">&nbsp;</div>

http://git-wip-us.apache.org/repos/asf/nifi/blob/8a751e80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/connection-details.css
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/connection-details.css b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/connection-details.css
index ce94485..c58febc 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/connection-details.css
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/connection-details.css
@@ -22,7 +22,7 @@
     z-index: 1301;
     display: none;
     width: 700px;
-    height: 400px;
+    height: 500px;
 }
 
 #connection-details div.configuration-tab {
@@ -40,4 +40,16 @@
 #connection-details div.relationship-name {
     display: inline-block;
     line-height: normal;
-}
\ No newline at end of file
+}
+
+.multi-column-settings {
+    display: flex;
+}
+
+.multi-column-settings .setting {
+    flex-grow: 1;
+}
+
+.multi-column-settings .separator {
+    min-width: 5px;
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/8a751e80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/graph.css
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/graph.css b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/graph.css
index 15daa76..8b1717b 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/graph.css
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/css/graph.css
@@ -320,13 +320,25 @@ g.connection path.connection-path.unauthorized {
     stroke-dasharray: 3,3;
 }
 
-text.connection-from-run-status, text.connection-to-run-status, text.expiration-icon {
+text.connection-from-run-status, text.connection-to-run-status, text.expiration-icon, text.load-balance-icon {
     fill: #728e9b;
     font-family: FontAwesome;
-    font-size: 10px;
+    font-size: 12px;
     text-shadow: 0 0 4px rgba(255,255,255,1);
 }
 
+text.load-balance-icon-active {
+    fill: #44a3cf
+}
+
+text.load-balance-icon-184 {
+    transform-origin: 189px 10px 0;
+}
+
+text.load-balance-icon-200 {
+    transform-origin: 205px 10px 0;
+}
+
 text.connection-from-run-status.is-missing-port, text.connection-to-run-status.is-missing-port {
     fill: #cf9f5d;
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/8a751e80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-connection-configuration.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-connection-configuration.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-connection-configuration.js
index 2d7938c..eb58df3 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-connection-configuration.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-connection-configuration.js
@@ -23,13 +23,14 @@
                 'd3',
                 'nf.ErrorHandler',
                 'nf.Common',
+                'nf.ClusterSummary',
                 'nf.Dialog',
                 'nf.Storage',
                 'nf.Client',
                 'nf.CanvasUtils',
                 'nf.Connection'],
-            function ($, d3, nfErrorHandler, nfCommon, nfDialog, nfStorage, nfClient, nfCanvasUtils, nfConnection) {
-                return (nf.ConnectionConfiguration = factory($, d3, nfErrorHandler, nfCommon, nfDialog, nfStorage, nfClient, nfCanvasUtils, nfConnection));
+            function ($, d3, nfErrorHandler, nfCommon, nfClusterSummary, nfDialog, nfStorage, nfClient, nfCanvasUtils, nfConnection) {
+                return (nf.ConnectionConfiguration = factory($, d3, nfErrorHandler, nfCommon, nfClusterSummary, nfDialog, nfStorage, nfClient, nfCanvasUtils, nfConnection));
             });
     } else if (typeof exports === 'object' && typeof module === 'object') {
         module.exports = (nf.ConnectionConfiguration =
@@ -37,6 +38,7 @@
                 require('d3'),
                 require('nf.ErrorHandler'),
                 require('nf.Common'),
+                require('nf.ClusterSummary'),
                 require('nf.Dialog'),
                 require('nf.Storage'),
                 require('nf.Client'),
@@ -47,13 +49,14 @@
             root.d3,
             root.nf.ErrorHandler,
             root.nf.Common,
+            root.nf.ClusterSummary,
             root.nf.Dialog,
             root.nf.Storage,
             root.nf.Client,
             root.nf.CanvasUtils,
             root.nf.Connection);
     }
-}(this, function ($, d3, nfErrorHandler, nfCommon, nfDialog, nfStorage, nfClient, nfCanvasUtils, nfConnection) {
+}(this, function ($, d3, nfErrorHandler, nfCommon, nfClusterSummary, nfDialog, nfStorage, nfClient, nfCanvasUtils, nfConnection) {
     'use strict';
 
     var nfBirdseye;
@@ -1007,6 +1010,10 @@
         var backPressureObjectThreshold = $('#back-pressure-object-threshold').val();
         var backPressureDataSizeThreshold = $('#back-pressure-data-size-threshold').val();
         var prioritizers = $('#prioritizer-selected').sortable('toArray');
+        var loadBalanceStrategy = $('#load-balance-strategy-combo').combo('getSelectedOption').value;
+        var shouldLoadBalance = 'DO_NOT_LOAD_BALANCE' !== loadBalanceStrategy;
+        var loadBalancePartitionAttribute = shouldLoadBalance && 'PARTITION_BY_ATTRIBUTE' === loadBalanceStrategy ? $('#load-balance-partition-attribute').val() : '';
+        var loadBalanceCompression = shouldLoadBalance ? $('#load-balance-compression-combo').combo('getSelectedOption').value : 'DO_NOT_COMPRESS';
 
         if (validateSettings()) {
             var d = nfConnection.get(connectionId);
@@ -1025,7 +1032,10 @@
                     'flowFileExpiration': flowFileExpiration,
                     'backPressureDataSizeThreshold': backPressureDataSizeThreshold,
                     'backPressureObjectThreshold': backPressureObjectThreshold,
-                    'prioritizers': prioritizers
+                    'prioritizers': prioritizers,
+                    'loadBalanceStrategy': loadBalanceStrategy,
+                    'loadBalancePartitionAttribute': loadBalancePartitionAttribute,
+                    'loadBalanceCompression': loadBalanceCompression
                 }
             };
 
@@ -1099,6 +1109,10 @@
         if (nfCommon.isBlank($('#back-pressure-data-size-threshold').val())) {
             errors.push('Back pressure data size threshold must be specified');
         }
+        if ($('#load-balance-strategy-combo').combo('getSelectedOption').value === 'PARTITION_BY_ATTRIBUTE'
+            && nfCommon.isBlank($('#load-balance-partition-attribute').val())) {
+            errors.push('Cannot set Load Balance Strategy to "Partition by attribute" without providing a partitioning "Attribute Name"');
+        }
 
         if (errors.length > 0) {
             nfDialog.showOkDialog({
@@ -1222,6 +1236,32 @@
                 }]
             });
 
+            // initialize the load balance strategy combo
+            $('#load-balance-strategy-combo').combo({
+                options: nfCommon.loadBalanceStrategyOptions,
+                select: function (selectedOption) {
+                    // Show the appropriate configurations
+                    if (selectedOption.value === 'PARTITION_BY_ATTRIBUTE') {
+                        $('#load-balance-partition-attribute-setting-separator').show();
+                        $('#load-balance-partition-attribute-setting').show();
+                    } else {
+                        $('#load-balance-partition-attribute-setting-separator').hide();
+                        $('#load-balance-partition-attribute-setting').hide();
+                    }
+                    if (selectedOption.value === 'DO_NOT_LOAD_BALANCE') {
+                        $('#load-balance-compression-setting').hide();
+                    } else {
+                        $('#load-balance-compression-setting').show();
+                    }
+                }
+            });
+
+
+            // initialize the load balance compression combo
+            $('#load-balance-compression-combo').combo({
+                options: nfCommon.loadBalanceCompressionOptions
+            });
+
             // load the processor prioritizers
             $.ajax({
                 type: 'GET',
@@ -1393,6 +1433,20 @@
                     $('#back-pressure-object-threshold').val(connection.backPressureObjectThreshold);
                     $('#back-pressure-data-size-threshold').val(connection.backPressureDataSizeThreshold);
 
+                    // select the load balance combos
+                    if (nfClusterSummary.isConnectedToCluster()) {
+                        $('#load-balance-strategy-combo').combo('setSelectedOption', {
+                            value: connection.loadBalanceStrategy
+                        });
+                        $('#load-balance-compression-combo').combo('setSelectedOption', {
+                            value: connection.loadBalanceCompression
+                        });
+                        $('#load-balance-partition-attribute').val(connection.loadBalancePartitionAttribute);
+                        $('#load-balance-settings').show();
+                    } else {
+                        $('#load-balance-settings').hide();
+                    }
+
                     // format the connection id
                     nfCommon.populateField('connection-id', connection.id);
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/8a751e80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-connection.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-connection.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-connection.js
index 145e1a3..e6d7b7d 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-connection.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-connection.js
@@ -60,7 +60,7 @@
 
     // the dimensions for the connection label
     var dimensions = {
-        width: 200
+        width: 216
     };
 
     // width of a backpressure indicator - half of width, left/right padding, left/right border
@@ -258,6 +258,16 @@
     };
 
     /**
+     * Determines whether load-balance is configured for the specified connection.
+     *
+     * @param {object} connection
+     * @return {boolean} Whether load-balance is configured
+     */
+    var isLoadBalanceConfigured = function (connection) {
+        return nfCommon.isDefinedAndNotNull(connection.loadBalanceStrategy) && 'DO_NOT_LOAD_BALANCE' !== connection.loadBalanceStrategy;
+    };
+
+    /**
      * Sorts the specified connections according to the z index.
      *
      * @param {type} connections
@@ -886,7 +896,7 @@
                                 connectionFrom.append('text')
                                     .attrs({
                                         'class': 'connection-from-run-status',
-                                        'x': 185,
+                                        'x': 200,
                                         'y': 14
                                     });
                             } else {
@@ -995,7 +1005,7 @@
                                 connectionTo.append('text')
                                     .attrs({
                                         'class': 'connection-to-run-status',
-                                        'x': 185,
+                                        'x': 200,
                                         'y': 14
                                     });
                             } else {
@@ -1195,11 +1205,23 @@
                                 'class': 'size'
                             });
 
+                        // load balance icon
+                        // x is set dynamically to slide to right, depending on whether expiration icon is shown.
+                        queued.append('text')
+                            .attrs({
+                                'class': 'load-balance-icon',
+                                'y': 14
+                            })
+                            .text(function () {
+                                return '\uf042';
+                            })
+                            .append('title');
+
                         // expiration icon
                         queued.append('text')
                             .attrs({
                                 'class': 'expiration-icon',
-                                'x': 185,
+                                'x': 200,
                                 'y': 14
                             })
                             .text(function () {
@@ -1341,6 +1363,52 @@
                         }
                     });
 
+                    // determine whether or not to show the load-balance icon
+                    connectionLabelContainer.select('text.load-balance-icon')
+                        .classed('hidden', function () {
+                            if (d.permissions.canRead) {
+                                return !isLoadBalanceConfigured(d.component);
+                            } else {
+                                return true;
+                            }
+                        }).classed('load-balance-icon-active fa-rotate-90', function (d) {
+                            return d.permissions.canRead && d.component.loadBalanceStatus === 'LOAD_BALANCE_ACTIVE';
+
+                        }).classed('load-balance-icon-184', function() {
+                            return d.permissions.canRead && isExpirationConfigured(d.component);
+
+                        }).classed('load-balance-icon-200', function() {
+                            return d.permissions.canRead && !isExpirationConfigured(d.component);
+
+                        }).attr('x', function() {
+                            return d.permissions.canRead && isExpirationConfigured(d.component) ? 184 : 200;
+
+                        }).select('title').text(function () {
+                            if (d.permissions.canRead) {
+                                var loadBalanceStrategy = nfCommon.getComboOptionText(nfCommon.loadBalanceStrategyOptions, d.component.loadBalanceStrategy);
+                                if ('PARTITION_BY_ATTRIBUTE' === d.component.loadBalanceStrategy) {
+                                    loadBalanceStrategy += ' (' + d.component.loadBalancePartitionAttribute + ')'
+                                }
+
+                                var loadBalanceCompression = 'no compression';
+                                switch (d.component.loadBalanceCompression) {
+                                    case 'COMPRESS_ATTRIBUTES_ONLY':
+                                        loadBalanceCompression = '\'Attribute\' compression';
+                                        break;
+                                    case 'COMPRESS_ATTRIBUTES_AND_CONTENT':
+                                        loadBalanceCompression = '\'Attribute and content\' compression';
+                                        break;
+                                }
+                                var loadBalanceStatus = 'LOAD_BALANCE_ACTIVE' === d.component.loadBalanceStatus ? ' Actively balancing...' : '';
+                                return 'Load Balance is configured'
+                                        + ' with \'' + loadBalanceStrategy + '\' strategy'
+                                        + ' and ' + loadBalanceCompression + '.'
+                                        + loadBalanceStatus;
+                            } else {
+                                return '';
+                            }
+                        });
+
                     // determine whether or not to show the expiration icon
                     connectionLabelContainer.select('text.expiration-icon')
                         .classed('hidden', function () {

http://git-wip-us.apache.org/repos/asf/nifi/blob/8a751e80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
index c07b95d..8dca0d8 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-common.js
@@ -1192,6 +1192,42 @@
         MILLIS_PER_SECOND: 1000,
 
         /**
+         * Constants for combo options.
+         */
+        loadBalanceStrategyOptions: [{
+                text: 'Do not load balance',
+                value: 'DO_NOT_LOAD_BALANCE',
+                description: 'Do not load balance FlowFiles between nodes in the cluster.'
+            }, {
+                text: 'Partition by attribute',
+                value: 'PARTITION_BY_ATTRIBUTE',
+                description: 'Determine which node to send a given FlowFile to based on the value of a user-specified FlowFile Attribute.'
+                                + ' All FlowFiles that have the same value for said Attribute will be sent to the same node in the cluster.'
+            }, {
+                text: 'Round robin',
+                value: 'ROUND_ROBIN',
+                description: 'FlowFiles will be distributed to nodes in the cluster in a Round-Robin fashion.'
+            }, {
+                text: 'Single node',
+                value: 'SINGLE_NODE',
+                description: 'All FlowFiles will be sent to the same node. Which node they are sent to is not defined.'
+        }],
+
+        loadBalanceCompressionOptions: [{
+                text: 'Do not compress',
+                value: 'DO_NOT_COMPRESS',
+                description: 'FlowFiles will not be compressed'
+            }, {
+                text: 'Compress attributes only',
+                value: 'COMPRESS_ATTRIBUTES_ONLY',
+                description: 'FlowFiles\' attributes will be compressed, but the FlowFiles\' contents will not be'
+            }, {
+                text: 'Compress attributes and content',
+                value: 'COMPRESS_ATTRIBUTES_AND_CONTENT',
+                description: 'FlowFiles\' attributes and content will be compressed'
+        }],
+
+        /**
          * Formats the specified duration.
          *
          * @param {integer} duration in millis
@@ -1650,7 +1686,22 @@
          */
         getComponentName: function (entity) {
             return entity.permissions.canRead === true ? entity.component.name : entity.id;
+        },
+
+        /**
+         * Find the corresponding combo option text from a combo option values.
+         *
+         * @param {object} options    The combo option array
+         * @param {string} value      The target value
+         * @returns {string}          The matched option text or undefined if not found
+         */
+        getComboOptionText: function (options, value) {
+            var matchedOption = options.find(function (option) {
+                return option.value === value;
+            });
+            return nfCommon.isDefinedAndNotNull(matchedOption) ? matchedOption.text : undefined;
         }
+
     };
 
     return nfCommon;

http://git-wip-us.apache.org/repos/asf/nifi/blob/8a751e80/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-connection-details.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-connection-details.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-connection-details.js
index a6538a9..b1632b3 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-connection-details.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/nf-connection-details.js
@@ -21,20 +21,23 @@
     if (typeof define === 'function' && define.amd) {
         define(['jquery',
                 'nf.Common',
+                'nf.ClusterSummary',
                 'nf.ErrorHandler'],
-            function ($, nfCommon, nfErrorHandler) {
-                return (nf.ConnectionDetails = factory($, nfCommon, nfErrorHandler));
+            function ($, nfCommon, nfClusterSummary, nfErrorHandler) {
+                return (nf.ConnectionDetails = factory($, nfCommon, nfClusterSummary, nfErrorHandler));
             });
     } else if (typeof exports === 'object' && typeof module === 'object') {
         module.exports = (nf.ConnectionDetails = factory(require('jquery'),
             require('nf.Common'),
+            require('nf.ClusterSummary'),
             require('nf.ErrorHandler')));
     } else {
         nf.ConnectionDetails = factory(root.$,
             root.nf.Common,
+            root.nf.ClusterSummary,
             root.nf.ErrorHandler);
     }
-}(this, function ($, nfCommon, nfErrorHandler) {
+}(this, function ($, nfCommon, nfClusterSummary, nfErrorHandler) {
     'use strict';
 
     /**
@@ -427,9 +430,12 @@
                         $('#read-only-relationship-names').css('border-width', '0').empty();
 
                         // clear the connection settings
-                        $('#read-only-flow-file-expiration').text('');
-                        $('#read-only-back-pressure-object-threshold').text('');
-                        $('#read-only-back-pressure-data-size-threshold').text('');
+                        nfCommon.clearField('read-only-flow-file-expiration');
+                        nfCommon.clearField('read-only-back-pressure-object-threshold');
+                        nfCommon.clearField('read-only-back-pressure-data-size-threshold');
+                        nfCommon.clearField('read-only-load-balance-strategy');
+                        nfCommon.clearField('read-only-load-balance-partition-attribute');
+                        nfCommon.clearField('read-only-load-balance-compression');
                         $('#read-only-prioritizers').empty();
                     },
                     open: function () {
@@ -446,6 +452,7 @@
          * @argument {string} connectionId      The connection id
          */
         showDetails: function (groupId, connectionId) {
+
             // get the group details
             var groupXhr = $.ajax({
                 type: 'GET',
@@ -521,6 +528,27 @@
                         nfCommon.populateField('read-only-flow-file-expiration', connection.flowFileExpiration);
                         nfCommon.populateField('read-only-back-pressure-object-threshold', connection.backPressureObjectThreshold);
                         nfCommon.populateField('read-only-back-pressure-data-size-threshold', connection.backPressureDataSizeThreshold);
+                        nfCommon.populateField('read-only-load-balance-strategy', nfCommon.getComboOptionText(nfCommon.loadBalanceStrategyOptions, connection.loadBalanceStrategy));
+                        nfCommon.populateField('read-only-load-balance-partition-attribute', connection.loadBalancePartitionAttribute);
+                        nfCommon.populateField('read-only-load-balance-compression', nfCommon.getComboOptionText(nfCommon.loadBalanceCompressionOptions, connection.loadBalanceCompression));
+
+                        // Show the appropriate load-balance configurations
+                        if (nfClusterSummary.isConnectedToCluster()) {
+                            if (connection.loadBalanceStrategy === 'PARTITION_BY_ATTRIBUTE') {
+                                $('#read-only-load-balance-partition-attribute-setting').show();
+                            } else {
+                                $('#read-only-load-balance-partition-attribute-setting').hide();
+                            }
+                            if (connection.loadBalanceStrategy === 'DO_NOT_LOAD_BALANCE') {
+                                $('#read-only-load-balance-compression-setting').hide();
+                            } else {
+                                $('#read-only-load-balance-compression-setting').show();
+                            }
+                            $('#read-only-load-balance-settings').show();
+                        } else {
+                            $('#read-only-load-balance-settings').hide();
+                        }
+
 
                         // prioritizers
                         if (nfCommon.isDefinedAndNotNull(connection.prioritizers) && connection.prioritizers.length > 0) {