Source:
<code>synchronized Map<String, String> getFlowMetadata(final FlowRunner flowRunner) { final ExecutableFlow flow = flowRunner.getExecutableFlow(); final Props props = ServiceProvider.SERVICE_PROVIDER.getInstance(Props.class); final Map<String, String> metaData = new HashMap<>(); metaData.put("flowName", flow.getId()); metaData.put("azkabanHost", props.getString(AZKABAN_SERVER_HOST_NAME, "unknown")); metaData.put("azkabanWebserver", props.getString(AZKABAN_WEBSERVER_EXTERNAL_HOSTNAME, props.getString("jetty.hostname", "localhost"))); metaData.put("projectName", flow.getProjectName()); metaData.put("submitUser", flow.getSubmitUser()); metaData.put("executionId", String.valueOf(flow.getExecutionId())); metaData.put("startTime", String.valueOf(flow.getStartTime())); metaData.put("submitTime", String.valueOf(flow.getSubmitTime())); final ProjectFileHandler handler = flowRunner.projectFileHandler; if (handler != null) { <START> metaData.put("uploadUser", handler.getUploader()); <END> metaData.put("uploaderIpAddr", handler.getUploaderIpAddr()); metaData.put("projectFileName", handler.getFileName()); metaData.put("projectFileUploadTime", String.valueOf(handler.getUploadTime())); } if (FlowLoaderUtils.isAzkabanFlowVersion20(flow.getAzkabanFlowVersion())) { FlowRunner.propagateMetadataFromProps(metaData, flow.getInputProps(), "flow", flow.getId(), FlowRunner.this.logger); } else { Props combinedProps = new Props(); for (final Props sharedProp : flowRunner.sharedProps.values()) { combinedProps.putAll(sharedProp.getFlattened()); } combinedProps = new Props(combinedProps, flow.getInputProps()); FlowRunner.propagateMetadataFromProps(metaData, combinedProps, "flow", flow.getId(), FlowRunner.this.logger); } return metaData; }</code><technical_language>additional properties added require a change in other places (1) EventReporter plugi: li-azkaban-plugins/azkaban-event-reporter/src/main/java/com/linkedin/azkaban/plugins/AzkabanKafkaAvroEventReporter.java (2) Avro Schema: avro-schemas/avro-schemas/avro-schemas-tracking/schemas/tracking/events/azkaban/AzkabanFlowLifeCycleEvent.avsc change</technical_language>

Target:
synchronized Map<String, String> getFlowMetadata(final FlowRunner flowRunner) { final ExecutableFlow flow = flowRunner.getExecutableFlow(); final Props props = ServiceProvider.SERVICE_PROVIDER.getInstance(Props.class); final Map<String, String> metaData = new HashMap<>(); metaData.put("flowName", flow.getId()); metaData.put("azkabanHost", props.getString(AZKABAN_SERVER_HOST_NAME, "unknown")); metaData.put("azkabanWebserver", props.getString(AZKABAN_WEBSERVER_EXTERNAL_HOSTNAME, props.getString("jetty.hostname", "localhost"))); metaData.put("projectName", flow.getProjectName()); metaData.put("submitUser", flow.getSubmitUser()); metaData.put("executionId", String.valueOf(flow.getExecutionId())); metaData.put("startTime", String.valueOf(flow.getStartTime())); metaData.put("submitTime", String.valueOf(flow.getSubmitTime())); final ProjectFileHandler handler = flowRunner.projectFileHandler; metaData.put("projectFileUploadUser", handler.getUploader()); metaData.put("projectFileUploaderIpAddr", handler.getUploaderIpAddr()); metaData.put("projectFileName", handler.getFileName()); metaData.put("projectFileUploadTime", String.valueOf(handler.getUploadTime())); if (FlowLoaderUtils.isAzkabanFlowVersion20(flow.getAzkabanFlowVersion())) { FlowRunner.propagateMetadataFromProps(metaData, flow.getInputProps(), "flow", flow.getId(), FlowRunner.this.logger); } else { Props combinedProps = new Props(); for (final Props sharedProp : flowRunner.sharedProps.values()) { combinedProps.putAll(sharedProp.getFlattened()); } combinedProps = new Props(combinedProps, flow.getInputProps()); FlowRunner.propagateMetadataFromProps(metaData, combinedProps, "flow", flow.getId(), FlowRunner.this.logger); } return metaData; }