You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@nifi.apache.org by GitBox <gi...@apache.org> on 2022/06/28 15:50:21 UTC

[GitHub] [nifi] exceptionfactory commented on a diff in pull request #6163: NIFI-10162 Reorganize InvokeHTTP Properties

exceptionfactory commented on code in PR #6163:
URL: https://github.com/apache/nifi/pull/6163#discussion_r908648841


##########
nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/InvokeHTTP.java:
##########
@@ -166,367 +170,355 @@ public class InvokeHTTP extends AbstractProcessor {
 
     public static final String DEFAULT_CONTENT_TYPE = "application/octet-stream";
 
-    public static final String FORM_BASE = "post:form";
-
-    // Set of flowfile attributes which we generally always ignore during
-    // processing, including when converting http headers, copying attributes, etc.
-    // This set includes our strings defined above as well as some standard flowfile
-    // attributes.
-    public static final Set<String> IGNORED_ATTRIBUTES = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
-            STATUS_CODE, STATUS_MESSAGE, RESPONSE_BODY, REQUEST_URL, RESPONSE_URL, TRANSACTION_ID, REMOTE_DN,
-            EXCEPTION_CLASS, EXCEPTION_MESSAGE,
-            "uuid", "filename", "path")));
-
-    public static final String HTTP = "http";
-    public static final String HTTPS = "https";
-
-    public static final String GET_METHOD = "GET";
-    public static final String POST_METHOD = "POST";
-    public static final String PUT_METHOD = "PUT";
-    public static final String PATCH_METHOD = "PATCH";
-    public static final String DELETE_METHOD = "DELETE";
-    public static final String HEAD_METHOD = "HEAD";
-    public static final String OPTIONS_METHOD = "OPTIONS";
-
-    private static final Pattern DYNAMIC_FORM_PARAMETER_NAME = Pattern.compile("post:form:(?<formDataName>.*)$");
+    protected static final String FORM_DATA_NAME_BASE = "post:form";
+    private static final Pattern FORM_DATA_NAME_PARAMETER_PATTERN = Pattern.compile("post:form:(?<formDataName>.*)$");
     private static final String FORM_DATA_NAME_GROUP = "formDataName";
-    private static final String CONTENT_ENCODING_HEADER = "Content-Encoding";
 
-    // properties
-    public static final PropertyDescriptor PROP_METHOD = new PropertyDescriptor.Builder()
+    private static final Set<String> IGNORED_REQUEST_ATTRIBUTES = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
+            STATUS_CODE,
+            STATUS_MESSAGE,
+            RESPONSE_BODY,
+            REQUEST_URL,
+            RESPONSE_URL,
+            TRANSACTION_ID,
+            REMOTE_DN,
+            EXCEPTION_CLASS,
+            EXCEPTION_MESSAGE,
+            CoreAttributes.UUID.key(),
+            CoreAttributes.FILENAME.key(),
+            CoreAttributes.PATH.key()
+    )));
+
+    public static final PropertyDescriptor HTTP_METHOD = new PropertyDescriptor.Builder()
             .name("HTTP Method")
             .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_METHOD)
+            .defaultValue(HttpMethod.GET.name())
             .expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
             .addValidator(StandardValidators.createAttributeExpressionLanguageValidator(AttributeExpression.ResultType.STRING))
             .build();
 
-    public static final PropertyDescriptor PROP_URL = new PropertyDescriptor.Builder()
+    public static final PropertyDescriptor HTTP_URL = new PropertyDescriptor.Builder()
             .name("Remote URL")
-            .description("Remote URL which will be connected to, including scheme, host, port, path.")
+            .displayName("HTTP URL")
+            .description("HTTP remote URL including a scheme of http or https, as well as a hostname or IP address with optional port and path elements.")
             .required(true)
             .expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
             .addValidator(StandardValidators.URL_VALIDATOR)
             .build();
 
-    public static final PropertyDescriptor PROP_CONNECT_TIMEOUT = new PropertyDescriptor.Builder()
+    public static final PropertyDescriptor HTTP2_DISABLED = new PropertyDescriptor.Builder()
+            .name("disable-http2")
+            .displayName("HTTP/2 Disabled")
+            .description("Disable negotiation of HTTP/2 protocol. HTTP/2 requires TLS. HTTP/1.1 protocol supported is required when HTTP/2 is disabled.")
+            .required(true)
+            .defaultValue("False")
+            .allowableValues("True", "False")
+            .build();
+
+    public static final PropertyDescriptor SSL_CONTEXT_SERVICE = new PropertyDescriptor.Builder()
+            .name("SSL Context Service")
+            .description("SSL Context Service provides trusted certificates and client certificates for TLS communication.")
+            .required(false)
+            .identifiesControllerService(SSLContextService.class)
+            .build();
+
+    public static final PropertyDescriptor SOCKET_CONNECT_TIMEOUT = new PropertyDescriptor.Builder()
             .name("Connection Timeout")
-            .description("Max wait time for connection to remote service.")
+            .displayName("Socket Connect Timeout")
+            .description("Maximum time to wait for initial socket connection to the HTTP URL.")
             .required(true)
             .defaultValue("5 secs")
             .addValidator(StandardValidators.TIME_PERIOD_VALIDATOR)
             .build();
 
-    public static final PropertyDescriptor PROP_READ_TIMEOUT = new PropertyDescriptor.Builder()
+    public static final PropertyDescriptor SOCKET_READ_TIMEOUT = new PropertyDescriptor.Builder()
             .name("Read Timeout")
-            .description("Max wait time for response from remote service.")
+            .displayName("Socket Read Timeout")
+            .description("Maximum time to wait for receiving responses from a socket connection to the HTTP URL.")
             .required(true)
             .defaultValue("15 secs")
             .addValidator(StandardValidators.TIME_PERIOD_VALIDATOR)
             .build();
 
-    public static final PropertyDescriptor PROP_IDLE_TIMEOUT = new PropertyDescriptor.Builder()
+    public static final PropertyDescriptor SOCKET_IDLE_TIMEOUT = new PropertyDescriptor.Builder()
             .name("idle-timeout")
-            .displayName("Idle Timeout")
-            .description("Max idle time before closing connection to the remote service.")
+            .displayName("Socket Idle Timeout")
+            .description("Maximum time to wait before closing idle connections to the HTTP URL.")
             .required(true)
             .defaultValue("5 mins")
             .addValidator(StandardValidators.createTimePeriodValidator(1, TimeUnit.MILLISECONDS, Integer.MAX_VALUE, TimeUnit.SECONDS))
             .build();
 
-    public static final PropertyDescriptor PROP_MAX_IDLE_CONNECTIONS = new PropertyDescriptor.Builder()
+    public static final PropertyDescriptor SOCKET_IDLE_CONNECTIONS = new PropertyDescriptor.Builder()
             .name("max-idle-connections")
-            .displayName("Max Idle Connections")
-            .description("Max number of idle connections to keep open.")
+            .displayName("Socket Idle Connections")
+            .description("Maximum number of idle connections to the HTTP URL.")
             .required(true)
             .defaultValue("5")
             .addValidator(StandardValidators.INTEGER_VALIDATOR)
             .build();
 
-    public static final PropertyDescriptor PROP_DATE_HEADER = new PropertyDescriptor.Builder()
-            .name("Include Date Header")
-            .description("Include an RFC-2616 Date header in the request.")
-            .required(true)
-            .defaultValue("True")
-            .allowableValues("True", "False")
-            .addValidator(StandardValidators.BOOLEAN_VALIDATOR)
-            .build();
-
-    public static final PropertyDescriptor PROP_FOLLOW_REDIRECTS = new PropertyDescriptor.Builder()
-            .name("Follow Redirects")
-            .description("Follow HTTP redirects issued by remote server.")
-            .required(true)
-            .defaultValue("True")
-            .allowableValues("True", "False")
-            .addValidator(StandardValidators.BOOLEAN_VALIDATOR)
-            .build();
-
-    public static final PropertyDescriptor PROP_ATTRIBUTES_TO_SEND = new PropertyDescriptor.Builder()
-            .name("Attributes to Send")
-            .description("Regular expression that defines which attributes to send as HTTP headers in the request. "
-                    + "If not defined, no attributes are sent as headers. Also any dynamic properties set will be sent as headers. "
-                    + "The dynamic property key will be the header key and the dynamic property value will be interpreted as expression "
-                    + "language will be the header value.")
-            .required(false)
-            .addValidator(StandardValidators.REGULAR_EXPRESSION_VALIDATOR)
-            .build();
-
-    public static final PropertyDescriptor PROP_USERAGENT = new PropertyDescriptor.Builder()
-            .name("Useragent")
-            .displayName("Useragent")
-            .description("The Useragent identifier sent along with each request")
+    @Deprecated
+    public static final PropertyDescriptor PROXY_HOST = new PropertyDescriptor.Builder()
+            .name("Proxy Host")
+            .description("Proxy Host and dependent properties are deprecated in favor of Proxy Configuration Service. Proxy Host can be configured using an IP address or DNS address.")
             .required(false)
-            .expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
             .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
+            .expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
             .build();
 
-    public static final PropertyDescriptor PROP_SSL_CONTEXT_SERVICE = new PropertyDescriptor.Builder()
-            .name("SSL Context Service")
-            .description("The SSL Context Service used to provide client certificate information for TLS/SSL (https) connections."
-                    + " It is also used to connect to HTTPS Proxy.")
+    @Deprecated
+    public static final PropertyDescriptor PROXY_PORT = new PropertyDescriptor.Builder()
+            .name("Proxy Port")
+            .description("Proxy Port and dependent properties are deprecated in favor of Proxy Configuration Service. Port number for the configured Proxy Host address.")
             .required(false)
-            .identifiesControllerService(SSLContextService.class)
+            .addValidator(StandardValidators.PORT_VALIDATOR)
+            .expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
+            .dependsOn(PROXY_HOST)
             .build();
 
-    public static final PropertyDescriptor PROP_PROXY_TYPE = new PropertyDescriptor.Builder()
+    @Deprecated
+    public static final PropertyDescriptor PROXY_TYPE = new PropertyDescriptor.Builder()
             .name("Proxy Type")
             .displayName("Proxy Type")
-            .description("The type of the proxy we are connecting to. Must be either " + HTTP + " or " + HTTPS)
-            .defaultValue(HTTP)
+            .description("Proxy Type and dependent properties are deprecated in favor of Proxy Configuration Service. Proxy protocol type is not used")
+            .defaultValue("http")
             .expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
             .addValidator(StandardValidators.NON_EMPTY_EL_VALIDATOR)
+            .dependsOn(PROXY_HOST)
             .build();
 
-    public static final PropertyDescriptor PROP_PROXY_HOST = new PropertyDescriptor.Builder()
-            .name("Proxy Host")
-            .description("The fully qualified hostname or IP address of the proxy server")
+    @Deprecated
+    public static final PropertyDescriptor PROXY_USERNAME = new PropertyDescriptor.Builder()
+            .name("invokehttp-proxy-user")
+            .displayName("Proxy Username")
+            .description("Proxy Username and dependent properties are deprecated in favor of Proxy Configuration Service. Username to set when authenticating with a Proxy server.")
             .required(false)
             .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
             .expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
+            .dependsOn(PROXY_HOST)
             .build();
 
-    public static final PropertyDescriptor PROP_PROXY_PORT = new PropertyDescriptor.Builder()
-            .name("Proxy Port")
-            .description("The port of the proxy server")
+    @Deprecated
+    public static final PropertyDescriptor PROXY_PASSWORD = new PropertyDescriptor.Builder()
+            .name("invokehttp-proxy-password")
+            .displayName("Proxy Password")
+            .description("Proxy Password and dependent properties are deprecated in favor of Proxy Configuration Service. Password to set when authenticating with a Proxy server.")
             .required(false)
-            .addValidator(StandardValidators.PORT_VALIDATOR)
+            .sensitive(true)
+            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
             .expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
+            .dependsOn(PROXY_HOST)
             .build();
 
-    public static final PropertyDescriptor PROP_PROXY_USER = new PropertyDescriptor.Builder()
-            .name("invokehttp-proxy-user")
-            .displayName("Proxy Username")
-            .description("Username to set when authenticating against proxy")
+    public static final PropertyDescriptor REQUEST_OAUTH2_ACCESS_TOKEN_PROVIDER = new PropertyDescriptor.Builder()
+            .name("oauth2-access-token-provider")
+            .displayName("Request OAuth2 Access Token Provider")
+            .description("Enables managed retrieval of OAuth2 Bearer Token applied to HTTP requests using the Authorization Header.")
+            .identifiesControllerService(OAuth2AccessTokenProvider.class)
             .required(false)
-            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
-            .expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
             .build();
 
-    public static final PropertyDescriptor PROP_PROXY_PASSWORD = new PropertyDescriptor.Builder()
-            .name("invokehttp-proxy-password")
-            .displayName("Proxy Password")
-            .description("Password to set when authenticating against proxy")
+    public static final PropertyDescriptor REQUEST_USERNAME = new PropertyDescriptor.Builder()
+            .name("Basic Authentication Username")
+            .displayName("Request Username")
+            .description("The username provided for authentication of HTTP requests. Encoded using Base64 for HTTP Basic Authentication as described in RFC 7617.")
+            .required(false)
+            .addValidator(StandardValidators.createRegexMatchingValidator(Pattern.compile("^[\\x20-\\x39\\x3b-\\x7e\\x80-\\xff]+$")))
+            .build();
+
+    public static final PropertyDescriptor REQUEST_PASSWORD = new PropertyDescriptor.Builder()
+            .name("Basic Authentication Password")
+            .displayName("Request Password")
+            .description("The password provided for authentication of HTTP requests. Encoded using Base64 for HTTP Basic Authentication as described in RFC 7617.")
             .required(false)
             .sensitive(true)
-            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
-            .expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
+            .addValidator(StandardValidators.createRegexMatchingValidator(Pattern.compile("^[\\x20-\\x7e\\x80-\\xff]+$")))
             .build();
 
-    public static final PropertyDescriptor PROP_CONTENT_ENCODING = new PropertyDescriptor.Builder()
-            .name("Content-Encoding")
-            .displayName("Content-Encoding")
-            .description("HTTP Content-Encoding applied to request body during transmission. The receiving server must support the selected encoding to avoid request failures.")
-            .required(true)
-            .defaultValue(ContentEncodingStrategy.DISABLED.getValue())
-            .allowableValues(ContentEncodingStrategy.class)
+    public static final PropertyDescriptor REQUEST_DIGEST_AUTHENTICATION_ENABLED = new PropertyDescriptor.Builder()
+            .name("Digest Authentication")
+            .displayName("Request Digest Authentication Enabled")
+            .description("Enable Digest Authentication on HTTP requests with Username and Password credentials as described in RFC 7616.")
+            .required(false)
+            .defaultValue("false")
+            .allowableValues("true", "false")
+            .dependsOn(REQUEST_USERNAME)
             .build();
 
-    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, 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(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
-            .defaultValue("${" + CoreAttributes.MIME_TYPE.key() + "}")
-            .addValidator(StandardValidators.createAttributeExpressionLanguageValidator(AttributeExpression.ResultType.STRING))
+    public static final PropertyDescriptor REQUEST_FAILURE_PENALIZATION_ENABLED = new PropertyDescriptor.Builder()
+            .name("Penalize on \"No Retry\"")
+            .displayName("Request Failure Penalization Enabled")
+            .description("Enable penalization of request FlowFiles when receiving HTTP response with a status code between 400 and 499.")
+            .required(false)
+            .defaultValue(Boolean.FALSE.toString())
+            .allowableValues(Boolean.TRUE.toString(), Boolean.FALSE.toString())
             .build();
 
-    public static final PropertyDescriptor PROP_SEND_BODY = new PropertyDescriptor.Builder()
+    public static final PropertyDescriptor REQUEST_BODY_ENABLED = new PropertyDescriptor.Builder()
             .name("send-message-body")
-            .displayName("Send Message Body")
-            .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")
+            .displayName("Request Body Enabled")
+            .description("Enable sending HTTP request payload body for PATCH, POST, or PUT methods.")
+            .defaultValue(Boolean.TRUE.toString())
+            .allowableValues(Boolean.TRUE.toString(), Boolean.FALSE.toString())
             .required(false)
+            .dependsOn(HTTP_METHOD, HttpMethod.PATCH.name(), HttpMethod.POST.name(), HttpMethod.PUT.name())
             .build();
 
-    public static final PropertyDescriptor PROP_FORM_BODY_FORM_NAME = new PropertyDescriptor.Builder()
+    public static final PropertyDescriptor REQUEST_FORM_DATA_NAME = new PropertyDescriptor.Builder()
             .name("form-body-form-name")
-            .displayName("FlowFile Form Data Name")
-            .description("When Send Message Body is true, and FlowFile Form Data Name is set, "
-                    + " the FlowFile will be sent as the message body in multipart/form format with this value "
-                    + "as the form data name.")
+            .displayName("Request Multipart Form-Data Name")
+            .description("Enable sending HTTP request payload body as a named element of multipart/form-data.")
             .required(false)
             .addValidator(
-                    StandardValidators.createAttributeExpressionLanguageValidator(AttributeExpression.ResultType.STRING, true))
+                    StandardValidators.createAttributeExpressionLanguageValidator(AttributeExpression.ResultType.STRING, true)
+            )
             .expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
+            .dependsOn(REQUEST_BODY_ENABLED, Boolean.TRUE.toString())
             .build();
 
-    public static final PropertyDescriptor PROP_SET_FORM_FILE_NAME = new PropertyDescriptor.Builder()
+    public static final PropertyDescriptor REQUEST_FORM_DATA_FILENAME_ENABLED = new PropertyDescriptor.Builder()
             .name("set-form-filename")
-            .displayName("Set FlowFile Form Data File Name")
-            .description(
-                    "When Send Message Body is true, FlowFile Form Data Name is set, "
-                            + "and Set FlowFile Form Data File Name is true, the FlowFile's fileName value "
-                            + "will be set as the filename property of the form data.")
+            .displayName("Request Multipart Form-Data Filename Enabled")
+            .description("Enable sending the FlowFile filename attribute as the filename parameter in the Content-Disposition Header for multipart/form-data HTTP requests.")
             .required(false)
-            .defaultValue("true")
-            .allowableValues("true", "false")
+            .defaultValue(Boolean.TRUE.toString())
+            .allowableValues(Boolean.TRUE.toString(), Boolean.FALSE.toString())
+            .dependsOn(REQUEST_FORM_DATA_NAME)
             .build();
 
-    // Per RFC 7235, 2617, and 2616.
-    // basic-credentials = base64-user-pass
-    // base64-user-pass = userid ":" password
-    // userid = *<TEXT excluding ":">
-    // password = *TEXT
-    //
-    // OCTET = <any 8-bit sequence of data>
-    // CTL = <any US-ASCII control character (octets 0 - 31) and DEL (127)>
-    // LWS = [CRLF] 1*( SP | HT )
-    // TEXT = <any OCTET except CTLs but including LWS>
-    //
-    // Per RFC 7230, username & password in URL are now disallowed in HTTP and HTTPS URIs.
-    public static final PropertyDescriptor PROP_BASIC_AUTH_USERNAME = new PropertyDescriptor.Builder()
-            .name("Basic Authentication Username")
-            .displayName("Basic Authentication Username")
-            .description("The username to be used by the client to authenticate against the Remote URL.  Cannot include control characters (0-31), ':', or DEL (127).")
-            .required(false)
-            .addValidator(StandardValidators.createRegexMatchingValidator(Pattern.compile("^[\\x20-\\x39\\x3b-\\x7e\\x80-\\xff]+$")))
+    public static final PropertyDescriptor REQUEST_CHUNKED_TRANSFER_ENCODING_ENABLED = new PropertyDescriptor.Builder()
+            .name("Use Chunked Encoding")
+            .displayName("Request Chunked Transfer-Encoding Enabled")
+            .description("Enable sending HTTP requests with the Transfer-Encoding Header set to chunked, and disable sending the Content-Length Header. " +
+                    "Transfer-Encoding applies to the payload body in HTTP/1.1 requests as described in RFC 7230 Section 3.3.1")
+            .required(true)
+            .defaultValue(Boolean.FALSE.toString())
+            .allowableValues(Boolean.TRUE.toString(), Boolean.FALSE.toString())
+            .dependsOn(HTTP_METHOD, HttpMethod.PATCH.name(), HttpMethod.POST.name(), HttpMethod.PUT.name())
             .build();
 
-    public static final PropertyDescriptor PROP_BASIC_AUTH_PASSWORD = new PropertyDescriptor.Builder()
-            .name("Basic Authentication Password")
-            .displayName("Basic Authentication Password")
-            .description("The password to be used by the client to authenticate against the Remote URL.")
-            .required(false)
-            .sensitive(true)
-            .addValidator(StandardValidators.createRegexMatchingValidator(Pattern.compile("^[\\x20-\\x7e\\x80-\\xff]+$")))
+    public static final PropertyDescriptor REQUEST_CONTENT_ENCODING = new PropertyDescriptor.Builder()
+            .name("Content-Encoding")
+            .displayName("Request Content-Encoding")
+            .description("HTTP Content-Encoding applied to request body during transmission. The receiving server must support the selected encoding to avoid request failures.")
+            .required(true)
+            .defaultValue(ContentEncodingStrategy.DISABLED.getValue())
+            .allowableValues(ContentEncodingStrategy.class)
+            .dependsOn(HTTP_METHOD, HttpMethod.PATCH.name(), HttpMethod.POST.name(), HttpMethod.PUT.name())
             .build();
 
-    public static final PropertyDescriptor PROP_PUT_OUTPUT_IN_ATTRIBUTE = new PropertyDescriptor.Builder()
-            .name("Put Response Body In Attribute")
-            .description("If set, the response body received back will be put into an attribute of the original FlowFile instead of a separate "
-                    + "FlowFile. The attribute key to put to is determined by evaluating value of this property. ")
-            .addValidator(StandardValidators.createAttributeExpressionLanguageValidator(AttributeExpression.ResultType.STRING))
+    public static final PropertyDescriptor REQUEST_CONTENT_TYPE = new PropertyDescriptor.Builder()
+            .name("Content-Type")
+            .displayName("Request Content-Type")
+            .description("HTTP Content-Type Header applied to when sending an HTTP request payload body for PATCH, POST, or PUT methods. " +
+                    String.format("The Content-Type defaults to %s when not configured.", DEFAULT_CONTENT_TYPE))
+            .required(true)
             .expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
+            .defaultValue("${" + CoreAttributes.MIME_TYPE.key() + "}")
+            .addValidator(StandardValidators.createAttributeExpressionLanguageValidator(AttributeExpression.ResultType.STRING))
+            .dependsOn(HTTP_METHOD, HttpMethod.PATCH.name(), HttpMethod.POST.name(), HttpMethod.PUT.name())
             .build();
 
-    public static final PropertyDescriptor PROP_PUT_ATTRIBUTE_MAX_LENGTH = new PropertyDescriptor.Builder()
-            .name("Max Length To Put In Attribute")
-            .description("If routing the response body to an attribute of the original (by setting the \"Put response body in attribute\" "
-                    + "property or by receiving an error status code), the number of characters put to the attribute value will be at "
-                    + "most this amount. This is important because attributes are held in memory and large attributes will quickly "
-                    + "cause out of memory issues. If the output goes longer than this value, it will be truncated to fit. "
-                    + "Consider making this smaller if able.")
-            .addValidator(StandardValidators.POSITIVE_INTEGER_VALIDATOR)
-            .defaultValue("256")
+    public static final PropertyDescriptor REQUEST_DATE_HEADER_ENABLED = new PropertyDescriptor.Builder()
+            .name("Include Date Header")
+            .displayName("Request Date Header Enabled")
+            .description("Enable sending HTTP Date Header on HTTP requests as described in RFC 7231 Section 7.1.1.2.")
+            .required(true)
+            .defaultValue("True")
+            .allowableValues("True", "False")
+            .addValidator(StandardValidators.BOOLEAN_VALIDATOR)
             .build();
 
-    public static final PropertyDescriptor PROP_DIGEST_AUTH = new PropertyDescriptor.Builder()
-            .name("Digest Authentication")
-            .displayName("Use Digest Authentication")
-            .description("Whether to communicate with the website using Digest Authentication. 'Basic Authentication Username' and 'Basic Authentication Password' are used "
-                    + "for authentication.")
+    public static final PropertyDescriptor REQUEST_HEADER_ATTRIBUTES_PATTERN = new PropertyDescriptor.Builder()
+            .name("Attributes to Send")
+            .displayName("Request Header Attributes Pattern")
+            .description("Regular expression that defines which attributes to send as HTTP headers in the request. "
+                    + "If not defined, no attributes are sent as headers. Dynamic properties will be sent as headers. "
+                    + "The dynamic property name will be the header key and the dynamic property value will be interpreted as expression "
+                    + "language will be the header value.")
             .required(false)
-            .defaultValue("false")
-            .allowableValues("true", "false")
+            .addValidator(StandardValidators.REGULAR_EXPRESSION_VALIDATOR)
             .build();
 
-    public static final PropertyDescriptor PROP_OUTPUT_RESPONSE_REGARDLESS = new PropertyDescriptor.Builder()
-            .name("Always Output Response")
-            .description("Will force a response FlowFile to be generated and routed to the 'Response' relationship regardless of what the server status code received is "
-                    + "or if the processor is configured to put the server response body in the request attribute. In the later configuration a request FlowFile with the "
-                    + "response body in the attribute and a typical response FlowFile will be emitted to their respective relationships.")
+    public static final PropertyDescriptor REQUEST_USER_AGENT = new PropertyDescriptor.Builder()
+            .name("Useragent")
+            .displayName("Request User-Agent")
+            .description("HTTP User-Agent Header applied to requests. RFC 7231 Section 5.5.3 describes recommend formatting.")
             .required(false)
-            .defaultValue("false")
-            .allowableValues("true", "false")
+            .expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
+            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
             .build();
 
-    public static final PropertyDescriptor PROP_ADD_HEADERS_TO_REQUEST = new PropertyDescriptor.Builder()
-            .name("Add Response Headers to Request")
-            .description("Enabling this property saves all the response headers to the original request. This may be when the response headers are needed "
-                    + "but a response is not generated due to the status code received.")
-            .required(false)
-            .defaultValue("false")
-            .allowableValues("true", "false")
+    public static final PropertyDescriptor RESPONSE_BODY_ATTRIBUTE_NAME = new PropertyDescriptor.Builder()
+            .name("Put Response Body In Attribute")
+            .displayName("Response Body Attribute Name")
+            .description("FlowFile attribute name used to write an HTTP response payload body for FlowFiles transferred to the Original relationship.")
+            .addValidator(StandardValidators.createAttributeExpressionLanguageValidator(AttributeExpression.ResultType.STRING))
+            .expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
             .build();
 
-    public static final PropertyDescriptor PROP_USE_CHUNKED_ENCODING = new PropertyDescriptor.Builder()
-            .name("Use Chunked Encoding")
-            .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")
-            .allowableValues("true", "false")
+    public static final PropertyDescriptor RESPONSE_BODY_ATTRIBUTE_SIZE = new PropertyDescriptor.Builder()
+            .name("Max Length To Put In Attribute")
+            .displayName("Response Body Attribute Size")
+            .description("Maximum size in bytes applied when writing an HTTP response payload body to a FlowFile attribute. Attributes exceeding the maximum will be truncated.")
+            .addValidator(StandardValidators.POSITIVE_INTEGER_VALIDATOR)
+            .defaultValue("256")
+            .dependsOn(RESPONSE_BODY_ATTRIBUTE_NAME)
             .build();
 
-    public static final PropertyDescriptor PROP_PENALIZE_NO_RETRY = new PropertyDescriptor.Builder()
-            .name("Penalize on \"No Retry\"")
-            .description("Enabling this property will penalize FlowFiles that are routed to the \"No Retry\" relationship.")
-            .required(false)
-            .defaultValue("false")
-            .allowableValues("true", "false")
+    public static final PropertyDescriptor RESPONSE_BODY_IGNORED = new PropertyDescriptor.Builder()
+            .name("ignore-response-content")
+            .displayName("Response Body Ignored")
+            .description("Disable writing HTTP response payload FlowFiles to Response relationship")
+            .required(true)
+            .defaultValue(Boolean.FALSE.toString())
+            .allowableValues(Boolean.TRUE.toString(), Boolean.FALSE.toString())
             .build();
 
-    public static final PropertyDescriptor PROP_USE_ETAG = new PropertyDescriptor.Builder()
+    public static final PropertyDescriptor RESPONSE_CACHE_ENABLED = new PropertyDescriptor.Builder()
             .name("use-etag")
-            .description("Enable HTTP entity tag (ETag) support for HTTP requests.")
-            .displayName("Use HTTP ETag")
+            .displayName("Response Cache Enabled")

Review Comment:
   The [OkHttp Caching](https://square.github.io/okhttp/features/caching/) implementation is not specific to ETags, but including some mention of ETags in the description would be helpful given the current naming.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@nifi.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org