[ 
https://issues.apache.org/jira/browse/BEAM-12767?focusedWorklogId=638708&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-638708
 ]

ASF GitHub Bot logged work on BEAM-12767:
-----------------------------------------

                Author: ASF GitHub Bot
            Created on: 17/Aug/21 15:33
            Start Date: 17/Aug/21 15:33
    Worklog Time Spent: 10m 
      Work Description: steveniemitz commented on a change in pull request 
#15338:
URL: https://github.com/apache/beam/pull/15338#discussion_r690488023



##########
File path: 
sdks/java/core/src/main/java/org/apache/beam/sdk/options/PipelineOptionsFactory.java
##########
@@ -1572,6 +1588,63 @@ public int compare(Method o1, Method o2) {
     return builder.build();
   }
 
+  /**
+   * Attempt to parse an input string into an instance of `type` using an 
{@link ObjectMapper}.
+   *
+   * <p>If the getter method is annotated with {@link
+   * com.fasterxml.jackson.databind.annotation.JsonDeserialize} the specified 
deserializer will be
+   * used, otherwise the default ObjectMapper deserialization strategy.
+   *
+   * <p>Parsing is attempted twice, once with the raw string value. If that 
attempt fails, another
+   * attempt is made by wrapping the value in quotes so that it is interpreted 
as a JSON string.
+   */
+  private static Object tryParseObject(String value, JavaType type, Method 
method)
+      throws IOException {
+    AnnotationCollector ac = AnnotationCollector.emptyCollector();
+    for (Annotation ann : method.getAnnotations()) {
+      ac = ac.addOrOverride(ann);
+    }
+
+    AnnotatedMethod annotatedMethod =
+        new AnnotatedMethod(
+            new TypeResolutionContext.Empty(MAPPER.getTypeFactory()),
+            method,
+            ac.asAnnotationMap(),
+            null);
+
+    BeanPropertyDefinition propDef =
+        
SimpleBeanPropertyDefinition.construct(MAPPER.getDeserializationConfig(), 
annotatedMethod);
+
+    BeanProperty prop =
+        new MethodProperty(
+            propDef,
+            type,
+            MAPPER.getDeserializationConfig().findTypeDeserializer(type),
+            ac.asAnnotations(),
+            annotatedMethod);
+
+    JsonNode tree;
+    try {
+      tree = MAPPER.readTree(value);
+    } catch (JsonParseException e) {
+      // try again, quoting the input string if it wasn't already
+      if (!(value.startsWith("\"") && value.endsWith("\""))) {
+        try {
+          tree = MAPPER.readTree("\"" + value + "\"");
+        } catch (JsonParseException inner) {
+          // rethrow the original exception rather the one thrown from the 
fallback attempt
+          throw e;
+        }
+      } else {
+        throw e;
+      }
+    }
+
+    JsonParser parser = new TreeTraversingParser(tree, MAPPER);
+    parser.nextToken();
+    return DESERIALIZATION_CONTEXT.readPropertyValue(parser, prop, type);

Review comment:
       As a point of conversation, I'm curious what people think of using the 
built-in jackson `@JsonDeserialize` vs making our own attribute?  The downside 
I see of the built-in attribute is that other things may parse pipeline options 
(dataflow for example writes it out as json), and this will affect that 
deserialization as well.
   
   We could have a `@ParseFunction` attribute or similar to map String -> T 
instead possibly, which would only be used from PipelineOptionsFactory.
   
   Curious what people's thoughts are.




-- 
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: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


Issue Time Tracking
-------------------

    Worklog Id:     (was: 638708)
    Time Spent: 20m  (was: 10m)

> Improve UX of PipelineOptions parsing
> -------------------------------------
>
>                 Key: BEAM-12767
>                 URL: https://issues.apache.org/jira/browse/BEAM-12767
>             Project: Beam
>          Issue Type: Improvement
>          Components: sdk-java-core
>            Reporter: Steve Niemitz
>            Assignee: Steve Niemitz
>            Priority: P2
>          Time Spent: 20m
>  Remaining Estimate: 0h
>
> Attempting to parse complex types in PipelineOptions can have a suboptimal 
> UX.  For example, if the option type being parsed is an Instant, simply 
> passing in:
> {{--myInstant=2021-07-17 }}{{will fail.  Instead the user must pass in 
> --myInstant="2021-07-17"}}{{, however, this is complicated by the fact that 
> the quotes will be stripped from the arguments in many cases, requiring a 
> user to actually pass in --myInstant='"2021-07-17"'.  }}
> This can be improved by attempting to parse the input twice, once as-is, and 
> then trying again by automatically wrapping it in quotes.
> Additionally, it's impossible to use a custom JsonDeserializer on a pipeline 
> option property.  We should allow using @JsonDeserialize on the getters to 
> supply a custom one.



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to