From 561f5b740a65a00e938b48c10c370279a27faf20 Mon Sep 17 00:00:00 2001 From: Matt Gilman Date: Fri, 15 Jan 2016 11:22:26 -0500 Subject: [PATCH] NIFI-1383: - Ensuring that nodes are not kicked out of the cluster when failing to successfully process a mutable request (like copy/paste). - Showing a more descriptive error message when possible. - Ensuring we don't try to instantiate an incomplete flow snippet. --- .../manager/impl/WebClusterManager.java | 11 ++++++++-- .../apache/nifi/web/util/SnippetUtils.java | 5 +++++ .../main/webapp/js/nf/canvas/nf-actions.js | 20 ++++++++++--------- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/impl/WebClusterManager.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/impl/WebClusterManager.java index 77005b6e3b..cc73c2825e 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/impl/WebClusterManager.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/manager/impl/WebClusterManager.java @@ -3463,8 +3463,15 @@ public class WebClusterManager implements HttpClusterManager, ProtocolHandler, C */ if (mutableRequest) { - // if some (not all) nodes had a problematic response because of a missing counter, ensure the are not disconnected - if (!problematicNodeResponses.isEmpty() && problematicNodeResponses.size() < nodeResponses.size() && isMissingCounter(problematicNodeResponses, uri)) { + // all nodes failed + final boolean allNodesFailed = problematicNodeResponses.size() == nodeResponses.size(); + + // some nodes had a problematic response because of a missing counter, ensure the are not disconnected + final boolean someNodesFailedMissingCounter = !problematicNodeResponses.isEmpty() && + problematicNodeResponses.size() < nodeResponses.size() && isMissingCounter(problematicNodeResponses, uri); + + // ensure nodes stay connected in certain scenarios + if (allNodesFailed || someNodesFailedMissingCounter) { for (final Map.Entry updatedNodeEntry : updatedNodesMap.entrySet()) { final NodeResponse nodeResponse = updatedNodeEntry.getValue(); final Node node = updatedNodeEntry.getKey(); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/util/SnippetUtils.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/util/SnippetUtils.java index 5f74a0e071..e1df3822c0 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/util/SnippetUtils.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/util/SnippetUtils.java @@ -534,6 +534,11 @@ public final class SnippetUtils { final ConnectableDTO source = connectableMap.get(cp.getSource().getGroupId() + "-" + cp.getSource().getId()); final ConnectableDTO destination = connectableMap.get(cp.getDestination().getGroupId() + "-" + cp.getDestination().getId()); + // ensure all referenced components are present + if (source == null || destination == null) { + throw new IllegalArgumentException("The flow snippet contains a Connection that references a component that is not included."); + } + cp.setId(generateId(connectionDTO.getId())); cp.setSource(source); cp.setDestination(destination); diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-actions.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-actions.js index 84d3ee3391..5343323d18 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-actions.js +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-actions.js @@ -1288,8 +1288,8 @@ nf.Actions = (function () { // perform the paste nf.Clipboard.paste().done(function (data) { var copySnippet = $.Deferred(function (deferred) { - var reject = function () { - deferred.reject(); + var reject = function (xhr, status, error) { + deferred.reject(xhr.responseText); }; // create a snippet from the details @@ -1332,18 +1332,20 @@ nf.Actions = (function () { // refresh the birdseye/toolbar nf.Birdseye.refresh(); }); - - // reject the deferred - reject(); - }); + }).fail(reject); }).fail(reject); }).promise(); // show the appropriate message is the copy fails - copySnippet.fail(function () { - // unable to create the template + copySnippet.fail(function (responseText) { + // look for a message + var message = 'An error occurred while attempting to copy and paste.'; + if ($.trim(responseText) !== '') { + message = responseText; + } + nf.Dialog.showOkDialog({ - dialogContent: 'An error occurred while attempting to copy and paste.', + dialogContent: nf.Common.escapeHtml(message), overlayBackground: true }); });