Skip to content

Conversation

zentol
Copy link
Contributor

@zentol zentol commented Jul 13, 2018

What is the purpose of the change

With this PR it is now possible to configure the submission via the JarRunHandler with a JSON payload instead of query parameters.
This has a number of advantages:

  • savepoint paths no longer have to be escaped to ridiculous degrees
  • program arguments are no longer limited in length (issue raised in FLINK9499)
  • arguments are transmitted as is and aren't subject to query parameter parsing rules (FLINK-9832)

The handler now accepts the configuration both via JSON and query parameters, with JSON being prioritized. The WebUI makes use of this to be compatible with both new and legacy handlers, which is pretty rad.

Note that the JarPlanHandler still suffers from the problems listed above. While this handler technically works similar to the JarRunHandler (in fact we could adjust it to work the same way) it unfortunately is a GET request, for which we do not allow payloads.

This PR shares some code with #6311.

  • simplification of dispatcher host retrieval
  • introduction of BlobServerResource

Brief change log

  • added JarRunRequestBody, with optional fields for all parameters
  • modified JarRunHandler to accept parameters both via JSON and query parameters
  • modified WebUI to submit configuration both via JSON and query parameters
    • new handlers will ignore query parameters
    • legacy handlers will ignore JSON

Verifying this change

This change added tests and can be verified as follows:

  • build flink-runtime-web (this step is important since we build jar for the test)
  • run JarRunHandlerParameterTest

The test verifies the successful submission with parameters

  • not being specified at all
  • being specified via query parameters
  • being specified via JSON request
  • being specified via both query parameters and JSON request.

Additionally, start a local cluster and manually submit jobs.

Does this pull request potentially affect one of the following parts:

  • Dependencies (does it add or upgrade a dependency): (no)
  • The public API, i.e., is any changed class annotated with @Public(Evolving): (yes)
  • The serializers: (no)
  • The runtime per-record code paths (performance sensitive): (no)
  • Anything that affects deployment or recovery: JobManager (and its components), Checkpointing, Yarn/Mesos, ZooKeeper: (no)
  • The S3 file system connector: (no)

Documentation

  • Does this pull request introduce a new feature? (yes)
  • If yes, how is the feature documented? (docs)

@zentol
Copy link
Contributor Author

zentol commented Jul 13, 2018

Currently preparing the documentation changes.

* {@link RequestBody} for running a jar.
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
public class JarRunRequestBody implements RequestBody {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing marshalling test

Copy link
Contributor

@tillrohrmann tillrohrmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your contribution @zentol. LGTM. I had some minor comments which we could address before merging this PR.

() -> getQueryParameter(request, AllowNonRestoredStateQueryParameter.class),
false,
log);
final String savepointPath = fromRequestBodyOrQueryParameter(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could add a fromRequestBodyOrQueryParameter method which does not take a default value as a convenience function. That way we would not have all the calls where we pass null.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could result in unexpected NullPointerExceptions when retrieving a primitive, like in the following example:

fromRequestBodyOrQueryParameter(
		requestBody.getParallelism(),
		() -> getQueryParameter(request, ParallelismQueryParameter.class)
		log);

The explicit default argument prevents that from happening.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't something like this work:

private static <T> T fromRequestBodyOrQueryParameter(
			T requestValue,
			SupplierWithException<T, RestHandlerException> queryParameterExtractor,
			Logger log) throws RestHandlerException {
                 return fromRequestBodyOrQueryParameter(requestValue, queryParameterExtractor, null, log);
	}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does this prevent the scenario i described?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, making the specification of the default value explicit will better guard against this. In the other case, the user would have to know the difference between these methods and which to apply to primitive and non-primitive values. Alright, then it's good to go from my side.

@JsonProperty(FIELD_NAME_PROGRAM_ARGUMENTS) String programArguments,
@JsonProperty(FIELD_NAME_PARALLELISM) Integer parallelism,
@JsonProperty(FIELD_NAME_ALLOW_NON_RESTORED_STATE) Boolean allowNonRestoredState,
@JsonProperty(FIELD_NAME_SAVEPOINT_PATH) String savepointPath) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the fields are @Nullable shouldn't the constructor parameters be also @Nullable? Or are the fields only @Nullable because of the default constructor?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes they should be nullable

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For example, if only a partial body is sent some fields may be null. I couldn't quickly find a way to allow either all fields or non to be null.

/**
* Tests for the parameter handling of the {@link JarRunHandler}.
*/
public class JarRunHandlerParameterTest {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should extend TestLogger.


return new HandlerRequest<>(
requestBody,
JarRunHeaders.getInstance().getUnresolvedMessageParameters(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we simply give the parameters parameter here instead of creating a new JarRunMessageParameters instance? Then we could also avoid having to create the queryParametersAsMap map.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HandlerRequest doesn't work like that.
It takes the parameter map from netty and inserts them into the MessageParameters.
We could move logic into a static factory method and have the request be a simple container, but changing that would be out-of-scope of this PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see. You're right. I think this could be a nice improvement to initialize the MessageParameter instance before giving it to the HandlerRequest. But this is out of scope for this PR.

asfgit pushed a commit that referenced this pull request Jul 19, 2018
@asfgit asfgit closed this in fefe866 Jul 19, 2018
zentol added a commit to zentol/flink that referenced this pull request Jul 19, 2018
@zentol zentol deleted the 9499 branch July 19, 2018 07:09
asfgit pushed a commit that referenced this pull request Jul 19, 2018
sampathBhat pushed a commit to sampathBhat/flink that referenced this pull request Jul 26, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants