azkaban-aplcache

Add logic to break down the property output into separate lines,

8/12/2015 8:01:21 PM

Details

diff --git a/azkaban-common/src/main/java/azkaban/jobExecutor/AbstractProcessJob.java b/azkaban-common/src/main/java/azkaban/jobExecutor/AbstractProcessJob.java
index 73592f0..c3ff1bf 100644
--- a/azkaban-common/src/main/java/azkaban/jobExecutor/AbstractProcessJob.java
+++ b/azkaban-common/src/main/java/azkaban/jobExecutor/AbstractProcessJob.java
@@ -43,6 +43,8 @@ public abstract class AbstractProcessJob extends AbstractJob {
   public static final String JOB_PROP_ENV = "JOB_PROP_FILE";
   public static final String JOB_NAME_ENV = "JOB_NAME";
   public static final String JOB_OUTPUT_PROP_FILE = "JOB_OUTPUT_PROP_FILE";
+  private static final String SENSITIVE_JOB_PROP_NAME_SURFFIX = "_X";
+  private static final String SENSITIVE_JOB_PROP_VALUE_PLACEHOLDER = "[MASKED]";
 
   protected final String _jobPath;
 
@@ -81,6 +83,24 @@ public abstract class AbstractProcessJob extends AbstractJob {
     jobProps = PropsUtils.resolveProps(jobProps);
   }
 
+  /**
+   * prints the current Job props to the Job log.
+   */
+  protected void logJobProperties() {
+    Map<String,String> flattenedProps = this.jobProps.getFlattened();
+    this.info("******   Job properties   ******");
+    this.info(String.format("- Note : value is masked if property name ends with '%s'.",
+                SENSITIVE_JOB_PROP_NAME_SURFFIX ));
+    for(Map.Entry<String, String> entry : flattenedProps.entrySet()){
+      String key = entry.getKey();
+      String value = key.endsWith(SENSITIVE_JOB_PROP_NAME_SURFFIX)?
+                                  SENSITIVE_JOB_PROP_VALUE_PLACEHOLDER :
+                                  entry.getValue();
+      this.info(String.format("%s=%s",key,value));
+    }
+    this.info("****** End Job properties  ******");
+  }
+
   @Override
   public Props getJobGeneratedProperties() {
     return generatedProperties;
@@ -101,7 +121,6 @@ public abstract class AbstractProcessJob extends AbstractJob {
 
     files[1] = createOutputPropsFile(getId(), _cwd);
     jobProps.put(ENV_PREFIX + JOB_OUTPUT_PROP_FILE, files[1].getAbsolutePath());
-
     return files;
   }
 
diff --git a/azkaban-common/src/main/java/azkaban/jobExecutor/LongArgJob.java b/azkaban-common/src/main/java/azkaban/jobExecutor/LongArgJob.java
index 6c71e52..6188e99 100644
--- a/azkaban-common/src/main/java/azkaban/jobExecutor/LongArgJob.java
+++ b/azkaban-common/src/main/java/azkaban/jobExecutor/LongArgJob.java
@@ -70,7 +70,7 @@ public abstract class LongArgJob extends AbstractProcessJob {
     File[] propFiles = initPropsFiles();
 
     // print out the Job properties to the job log.
-    info("Job properties:" + this.jobProps.getFlattened());
+    this.logJobProperties();
 
     boolean success = false;
     this.process = builder.build();
diff --git a/azkaban-common/src/main/java/azkaban/jobExecutor/ProcessJob.java b/azkaban-common/src/main/java/azkaban/jobExecutor/ProcessJob.java
index 8c3e2d8..4e268a0 100644
--- a/azkaban-common/src/main/java/azkaban/jobExecutor/ProcessJob.java
+++ b/azkaban-common/src/main/java/azkaban/jobExecutor/ProcessJob.java
@@ -94,7 +94,7 @@ public class ProcessJob extends AbstractProcessJob {
       info("Working directory: " + builder.getWorkingDir());
 
       // print out the Job properties to the job log.
-      info("Job properties:" + this.jobProps.getFlattened());
+      this.logJobProperties();
 
       boolean success = false;
       this.process = builder.build();
diff --git a/azkaban-common/src/main/java/azkaban/utils/Props.java b/azkaban-common/src/main/java/azkaban/utils/Props.java
index 882a60a..df28056 100644
--- a/azkaban-common/src/main/java/azkaban/utils/Props.java
+++ b/azkaban-common/src/main/java/azkaban/utils/Props.java
@@ -34,6 +34,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
+import java.util.TreeMap;
 
 import org.apache.log4j.Logger;
 
@@ -816,7 +817,11 @@ public class Props {
    * @Return
    */
   public Map<String,String> getFlattened(){
-    Map<String,String> returnVal = new HashMap<String,String>();
+
+    // creating a treeMap here so that the flattened list can be sorted
+    // alphabetically by the key value.
+    Map<String,String> returnVal = new TreeMap<String,String>();
+
     // to keep the logic in sync with the rest piece of code,
     // when there is a conflict, value from the child takes the priority.
     for (Props curr = this; curr != null; curr = curr.getParent()) {
diff --git a/azkaban-common/src/test/java/azkaban/utils/PropsUtilsTest.java b/azkaban-common/src/test/java/azkaban/utils/PropsUtilsTest.java
index b71aa8a..54464cd 100644
--- a/azkaban-common/src/test/java/azkaban/utils/PropsUtilsTest.java
+++ b/azkaban-common/src/test/java/azkaban/utils/PropsUtilsTest.java
@@ -159,6 +159,18 @@ public class PropsUtilsTest {
     Assert.assertEquals(5,set.size());
     Assert.assertEquals("value5", set.get("test5"));
     Assert.assertEquals("value1.1", set.get("test1"));
+
+    // verify when iterating the elements are sorted by the key value.
+    Props props2 = new Props();
+    props2.put("2","2");
+    props2.put("0","0");
+    props2.put("1","1");
+    set = props2.getFlattened();
+    int index = 0 ;
+    for (Map.Entry<String, String> item : set.entrySet())
+    {
+      Assert.assertEquals(item.getKey(),Integer.toString(index++));
+    }
   }
 
   @Test