Repository: nifi
Updated Branches:
  refs/heads/master 4f49095d7 -> f9c4d3ce3


NIFI-3508: Added support for PATCH identical to that of PUT/POST

This closes #1522.

Signed-off-by: ijokarumawak <[email protected]>


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

Branch: refs/heads/master
Commit: f9c4d3ce3ad29fd484feead456f28a8fad3e0684
Parents: 4f49095
Author: Nick Carenza <[email protected]>
Authored: Mon Feb 20 18:01:27 2017 -0800
Committer: ijokarumawak <[email protected]>
Committed: Tue Feb 21 16:23:23 2017 +0900

----------------------------------------------------------------------
 .../nifi/processors/standard/InvokeHTTP.java    | 18 ++--
 .../standard/util/TestInvokeHttpCommon.java     | 89 +++++++++++++++++++-
 2 files changed, 99 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi/blob/f9c4d3ce/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/InvokeHTTP.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/InvokeHTTP.java
 
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/InvokeHTTP.java
index 66f7561..12991ca 100644
--- 
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/InvokeHTTP.java
+++ 
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/InvokeHTTP.java
@@ -95,7 +95,7 @@ import org.joda.time.format.DateTimeFormatter;
 @Tags({"http", "https", "rest", "client"})
 @InputRequirement(Requirement.INPUT_ALLOWED)
 @CapabilityDescription("An HTTP client processor which can interact with a 
configurable HTTP Endpoint. The destination URL and HTTP Method are 
configurable."
-    + " FlowFile attributes are converted to HTTP headers and the FlowFile 
contents are included as the body of the request (if the HTTP Method is PUT or 
POST).")
+    + " FlowFile attributes are converted to HTTP headers and the FlowFile 
contents are included as the body of the request (if the HTTP Method is PUT, 
POST or PATCH).")
 @WritesAttributes({
     @WritesAttribute(attribute = "invokehttp.status.code", description = "The 
status code that is returned"),
     @WritesAttribute(attribute = "invokehttp.status.message", description = 
"The status message that is returned"),
@@ -138,8 +138,8 @@ public final class InvokeHTTP extends AbstractProcessor {
     // properties
     public static final PropertyDescriptor PROP_METHOD = new 
PropertyDescriptor.Builder()
             .name("HTTP Method")
-            .description("HTTP request method (GET, POST, PUT, DELETE, HEAD, 
OPTIONS). Arbitrary methods are also supported. "
-                + "Methods other than POST and PUT will be sent without a 
message body.")
+            .description("HTTP request method (GET, POST, PUT, PATCH, DELETE, 
HEAD, OPTIONS). Arbitrary methods are also supported. "
+                + "Methods other than POST, PUT and PATCH will be sent without 
a message body.")
             .required(true)
             .defaultValue("GET")
             .expressionLanguageSupported(true)
@@ -238,7 +238,7 @@ public final class InvokeHTTP extends AbstractProcessor {
 
     public static final PropertyDescriptor PROP_CONTENT_TYPE = new 
PropertyDescriptor.Builder()
         .name("Content-Type")
-        .description("The Content-Type to specify for when content is being 
transmitted through a PUT or POST. "
+        .description("The Content-Type to specify for when content is being 
transmitted through a PUT, POST or PATCH. "
             + "In the case of an empty value after evaluating an expression 
language expression, Content-Type defaults to " + DEFAULT_CONTENT_TYPE)
         .required(true)
         .expressionLanguageSupported(true)
@@ -249,7 +249,7 @@ public final class InvokeHTTP extends AbstractProcessor {
     public static final PropertyDescriptor PROP_SEND_BODY = new 
PropertyDescriptor.Builder()
             .name("send-message-body")
             .displayName("Send Message Body")
-            .description("If true, sends the HTTP message body on POST/PUT 
requests (default).  If false, suppresses the message body and content-type 
header for these requests.")
+            .description("If true, sends the HTTP message body on 
POST/PUT/PATCH requests (default).  If false, suppresses the message body and 
content-type header for these requests.")
             .defaultValue("true")
             .allowableValues("true", "false")
             .required(false)
@@ -343,7 +343,7 @@ public final class InvokeHTTP extends AbstractProcessor {
 
     public static final PropertyDescriptor PROP_USE_CHUNKED_ENCODING = new 
PropertyDescriptor.Builder()
             .name("Use Chunked Encoding")
-            .description("When POST'ing or PUT'ing content set this property 
to true in order to not pass the 'Content-length' header and instead send 
'Transfer-Encoding' with "
+            .description("When POST'ing, PUT'ing or PATCH'ing content set this 
property to true in order to not pass the 'Content-length' header and instead 
send 'Transfer-Encoding' with "
                     + "a value of 'chunked'. This will enable the data 
transfer mechanism which was introduced in HTTP 1.1 to pass data of unknown 
lengths in chunks.")
             .required(true)
             .defaultValue("false")
@@ -596,7 +596,7 @@ public final class InvokeHTTP extends AbstractProcessor {
             }
 
             String request = 
context.getProperty(PROP_METHOD).evaluateAttributeExpressions().getValue().toUpperCase();
-            if ("POST".equals(request) || "PUT".equals(request)) {
+            if ("POST".equals(request) || "PUT".equals(request) || 
"PATCH".equals(request)) {
                 return;
             } else if (putToAttribute) {
                 requestFlowFile = session.create();
@@ -809,6 +809,10 @@ public final class InvokeHTTP extends AbstractProcessor {
                 requestBody = getRequestBodyToSend(session, context, 
requestFlowFile);
                 requestBuilder = requestBuilder.put(requestBody);
                 break;
+            case "PATCH":
+                requestBody = getRequestBodyToSend(session, context, 
requestFlowFile);
+                requestBuilder = requestBuilder.patch(requestBody);
+                break;
             case "HEAD":
                 requestBuilder = requestBuilder.head();
                 break;

http://git-wip-us.apache.org/repos/asf/nifi/blob/f9c4d3ce/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/util/TestInvokeHttpCommon.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/util/TestInvokeHttpCommon.java
 
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/util/TestInvokeHttpCommon.java
index 5b1e404..5d460fe 100644
--- 
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/util/TestInvokeHttpCommon.java
+++ 
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/util/TestInvokeHttpCommon.java
@@ -1115,6 +1115,93 @@ public abstract class TestInvokeHttpCommon {
     }
 
     @Test
+    public void testPatch() throws Exception {
+        addHandler(new MutativeMethodHandler(MutativeMethod.PATCH));
+
+        runner.setProperty(InvokeHTTP.PROP_METHOD, "PATCH");
+        runner.setProperty(InvokeHTTP.PROP_URL, url + "/patch");
+
+        createFlowFiles(runner);
+
+        runner.run();
+        runner.assertTransferCount(InvokeHTTP.REL_SUCCESS_REQ, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_RESPONSE, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_NO_RETRY, 0);
+        runner.assertTransferCount(InvokeHTTP.REL_FAILURE, 0);
+        runner.assertPenalizeCount(0);
+
+        final MockFlowFile bundle = 
runner.getFlowFilesForRelationship(InvokeHTTP.REL_SUCCESS_REQ).get(0);
+        bundle.assertContentEquals("Hello".getBytes("UTF-8"));
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "200");
+        bundle.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "OK");
+        bundle.assertAttributeEquals("Foo", "Bar");
+
+        final MockFlowFile bundle1 = 
runner.getFlowFilesForRelationship(InvokeHTTP.REL_RESPONSE).get(0);
+        bundle1.assertContentEquals("".getBytes("UTF-8"));
+        bundle1.assertAttributeEquals(InvokeHTTP.STATUS_CODE, "200");
+        bundle1.assertAttributeEquals(InvokeHTTP.STATUS_MESSAGE, "OK");
+        bundle1.assertAttributeEquals("Foo", "Bar");
+        bundle1.assertAttributeNotExists("Content-Type");
+
+        final String actual1 = new String(bundle1.toByteArray(), 
StandardCharsets.UTF_8);
+        final String expected1 = "";
+        Assert.assertEquals(expected1, actual1);
+    }
+
+    @Test
+    public void testPatchWithMimeType() throws Exception {
+        final String suppliedMimeType = "text/plain";
+        addHandler(new MutativeMethodHandler(MutativeMethod.PATCH, 
suppliedMimeType));
+
+        runner.setProperty(InvokeHTTP.PROP_METHOD, "PATCH");
+        runner.setProperty(InvokeHTTP.PROP_URL, url + "/patch");
+
+        final Map<String, String> attrs = new HashMap<>();
+
+        attrs.put(CoreAttributes.MIME_TYPE.key(), suppliedMimeType);
+        runner.enqueue("Hello".getBytes(), attrs);
+
+        runner.run(1);
+        runner.assertTransferCount(InvokeHTTP.REL_SUCCESS_REQ, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_RESPONSE, 1);
+    }
+
+    @Test
+    public void testPatchWithEmptyELExpression() throws Exception {
+        addHandler(new MutativeMethodHandler(MutativeMethod.PATCH, 
InvokeHTTP.DEFAULT_CONTENT_TYPE));
+
+        runner.setProperty(InvokeHTTP.PROP_METHOD, "PATCH");
+        runner.setProperty(InvokeHTTP.PROP_URL, url + "/patch");
+
+        final Map<String, String> attrs = new HashMap<>();
+        attrs.put(CoreAttributes.MIME_TYPE.key(), "");
+        runner.enqueue("Hello".getBytes(), attrs);
+
+        runner.run(1);
+        runner.assertTransferCount(InvokeHTTP.REL_SUCCESS_REQ, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_RESPONSE, 1);
+    }
+
+    @Test
+    public void testPatchWithContentTypeProperty() throws Exception {
+        final String suppliedMimeType = "text/plain";
+        addHandler(new MutativeMethodHandler(MutativeMethod.PATCH, 
suppliedMimeType));
+
+        runner.setProperty(InvokeHTTP.PROP_METHOD, "PATCH");
+        runner.setProperty(InvokeHTTP.PROP_URL, url + "/patch");
+        runner.setProperty(InvokeHTTP.PROP_CONTENT_TYPE, suppliedMimeType);
+
+        final Map<String, String> attrs = new HashMap<>();
+        attrs.put(CoreAttributes.MIME_TYPE.key(), "text/csv");
+        runner.enqueue("Hello".getBytes(), attrs);
+
+        runner.run(1);
+        runner.assertTransferCount(InvokeHTTP.REL_SUCCESS_REQ, 1);
+        runner.assertTransferCount(InvokeHTTP.REL_RESPONSE, 1);
+    }
+
+    @Test
     public void testDelete() throws Exception {
         addHandler(new DeleteHandler());
 
@@ -1402,7 +1489,7 @@ public abstract class TestInvokeHttpCommon {
         }
     }
 
-    private enum MutativeMethod { POST, PUT }
+    private enum MutativeMethod { POST, PUT, PATCH }
 
 
     public static class MutativeMethodHandler extends AbstractHandler {

Reply via email to