[REEF-1633] Implement Configurations.getDefaultSerializer() and .toString() methods

Also, use Tang.toString() in REEF examples

JIRA:
  [REEF-1633](https://issues.apache.org/jira/browse/REEF-1633)

Pull Request:
  This closes #1149
diff --git a/lang/java/reef-common/src/main/java/org/apache/reef/runtime/common/REEFEnvironment.java b/lang/java/reef-common/src/main/java/org/apache/reef/runtime/common/REEFEnvironment.java
index 2809d44..c8a3d0e 100644
--- a/lang/java/reef-common/src/main/java/org/apache/reef/runtime/common/REEFEnvironment.java
+++ b/lang/java/reef-common/src/main/java/org/apache/reef/runtime/common/REEFEnvironment.java
@@ -27,7 +27,6 @@
 import org.apache.reef.tang.annotations.Name;
 import org.apache.reef.tang.annotations.NamedParameter;
 import org.apache.reef.tang.exceptions.InjectionException;
-import org.apache.reef.tang.formats.AvroConfigurationSerializer;
 import org.apache.reef.util.EnvironmentUtils;
 import org.apache.reef.util.REEFVersion;
 import org.apache.reef.wake.profiler.WakeProfiler;
@@ -73,9 +72,7 @@
     final Configuration config = Configurations.merge(configurations);
 
     if (LOG.isLoggable(Level.FINEST)) {
-      // TODO[REEF-1633] Obtain default serializer from Tang, or use Tang to pretty print.
-      LOG.log(Level.FINEST, "Configuration:\n--\n{0}\n--",
-          new AvroConfigurationSerializer().toString(config, true));
+      LOG.log(Level.FINEST, "Configuration:\n--\n{0}\n--", Configurations.toString(config, true));
     }
 
     final Injector injector = TANG.newInjector(config);
diff --git a/lang/java/reef-examples/src/main/java/org/apache/reef/examples/group/bgd/utils/SubConfiguration.java b/lang/java/reef-examples/src/main/java/org/apache/reef/examples/group/bgd/utils/SubConfiguration.java
index dff4dc3..835a130 100644
--- a/lang/java/reef-examples/src/main/java/org/apache/reef/examples/group/bgd/utils/SubConfiguration.java
+++ b/lang/java/reef-examples/src/main/java/org/apache/reef/examples/group/bgd/utils/SubConfiguration.java
@@ -21,14 +21,9 @@
 import org.apache.reef.driver.task.TaskConfiguration;
 import org.apache.reef.driver.task.TaskConfigurationOptions;
 import org.apache.reef.examples.group.bgd.MasterTask;
-import org.apache.reef.tang.Configuration;
-import org.apache.reef.tang.Injector;
-import org.apache.reef.tang.JavaConfigurationBuilder;
-import org.apache.reef.tang.Tang;
+import org.apache.reef.tang.*;
 import org.apache.reef.tang.annotations.Name;
 import org.apache.reef.tang.exceptions.InjectionException;
-import org.apache.reef.tang.formats.AvroConfigurationSerializer;
-import org.apache.reef.tang.formats.ConfigurationSerializer;
 
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -68,10 +63,9 @@
         .set(TaskConfiguration.TASK, MasterTask.class)
         .build();
 
-    final ConfigurationSerializer confSerizalizer = new AvroConfigurationSerializer();
     final Configuration subConf = SubConfiguration.from(conf, TaskConfigurationOptions.Identifier.class);
-    LOG.log(Level.INFO, "OUT: Base conf:\n{0}", confSerizalizer.toString(conf));
-    LOG.log(Level.INFO, "OUT: Sub conf:\n{0}", confSerizalizer.toString(subConf));
+    LOG.log(Level.INFO, "OUT: Base conf:\n{0}", Configurations.toString(conf));
+    LOG.log(Level.INFO, "OUT: Sub conf:\n{0}", Configurations.toString(subConf));
   }
 
   /**
diff --git a/lang/java/reef-examples/src/main/java/org/apache/reef/examples/group/broadcast/BroadcastREEF.java b/lang/java/reef-examples/src/main/java/org/apache/reef/examples/group/broadcast/BroadcastREEF.java
index 3b25bdb..103cc13 100644
--- a/lang/java/reef-examples/src/main/java/org/apache/reef/examples/group/broadcast/BroadcastREEF.java
+++ b/lang/java/reef-examples/src/main/java/org/apache/reef/examples/group/broadcast/BroadcastREEF.java
@@ -27,14 +27,10 @@
 import org.apache.reef.io.network.group.impl.driver.GroupCommService;
 import org.apache.reef.runtime.local.client.LocalRuntimeConfiguration;
 import org.apache.reef.runtime.yarn.client.YarnClientConfiguration;
-import org.apache.reef.tang.Configuration;
-import org.apache.reef.tang.Injector;
-import org.apache.reef.tang.JavaConfigurationBuilder;
-import org.apache.reef.tang.Tang;
+import org.apache.reef.tang.*;
 import org.apache.reef.tang.annotations.Name;
 import org.apache.reef.tang.annotations.NamedParameter;
 import org.apache.reef.tang.exceptions.InjectionException;
-import org.apache.reef.tang.formats.AvroConfigurationSerializer;
 import org.apache.reef.tang.formats.CommandLine;
 import org.apache.reef.util.EnvironmentUtils;
 
@@ -47,6 +43,7 @@
  */
 @ClientSide
 public final class BroadcastREEF {
+
   private static final Logger LOG = Logger.getLogger(BroadcastREEF.class.getName());
 
   private static final String MAX_NUMBER_OF_EVALUATORS = "20";
@@ -139,7 +136,10 @@
         .bindNamedParameter(NumberOfReceivers.class, Integer.toString(numberOfReceivers))
         .build();
 
-    LOG.info(new AvroConfigurationSerializer().toString(mergedDriverConfiguration));
+    if (LOG.isLoggable(Level.FINE)) {
+      LOG.log(Level.FINE, "Merged driver configuration:\n{0}",
+          Configurations.toString(mergedDriverConfiguration));
+    }
 
     return DriverLauncher.getLauncher(runtimeConfiguration).run(mergedDriverConfiguration, JOB_TIMEOUT);
   }
diff --git a/lang/java/reef-examples/src/main/java/org/apache/reef/examples/pool/Launch.java b/lang/java/reef-examples/src/main/java/org/apache/reef/examples/pool/Launch.java
index 84b9f7e..0e3281c 100644
--- a/lang/java/reef-examples/src/main/java/org/apache/reef/examples/pool/Launch.java
+++ b/lang/java/reef-examples/src/main/java/org/apache/reef/examples/pool/Launch.java
@@ -22,15 +22,11 @@
 import org.apache.reef.client.DriverLauncher;
 import org.apache.reef.runtime.local.client.LocalRuntimeConfiguration;
 import org.apache.reef.runtime.yarn.client.YarnClientConfiguration;
-import org.apache.reef.tang.Configuration;
-import org.apache.reef.tang.Injector;
-import org.apache.reef.tang.JavaConfigurationBuilder;
-import org.apache.reef.tang.Tang;
+import org.apache.reef.tang.*;
 import org.apache.reef.tang.annotations.Name;
 import org.apache.reef.tang.annotations.NamedParameter;
 import org.apache.reef.tang.exceptions.BindException;
 import org.apache.reef.tang.exceptions.InjectionException;
-import org.apache.reef.tang.formats.AvroConfigurationSerializer;
 import org.apache.reef.tang.formats.CommandLine;
 import org.apache.reef.util.EnvironmentUtils;
 
@@ -101,9 +97,10 @@
    * @throws InjectionException if configuration commandLineInjector fails.
    */
   private static Configuration getClientConfiguration(
-      final Configuration commandLineConf, final boolean isLocal)
-      throws BindException, InjectionException {
+      final Configuration commandLineConf, final boolean isLocal) throws BindException, InjectionException {
+
     final Configuration runtimeConfiguration;
+
     if (isLocal) {
       LOG.log(Level.FINE, "Running on the local runtime");
       runtimeConfiguration = LocalRuntimeConfiguration.CONF
@@ -113,9 +110,8 @@
       LOG.log(Level.FINE, "Running on YARN");
       runtimeConfiguration = YarnClientConfiguration.CONF.build();
     }
-    return Tang.Factory.getTang().newConfigurationBuilder(
-        runtimeConfiguration, cloneCommandLineConfiguration(commandLineConf))
-        .build();
+
+    return Configurations.merge(runtimeConfiguration, cloneCommandLineConfiguration(commandLineConf));
   }
 
   /**
@@ -144,7 +140,7 @@
 
       final Configuration runtimeConfig = getClientConfiguration(commandLineConf, isLocal);
       LOG.log(Level.INFO, "TIME: Start Client {0} with timeout {1} sec. Configuration:\n--\n{2}--",
-          new Object[]{jobId, timeout / 1000, new AvroConfigurationSerializer().toString(runtimeConfig)});
+          new Object[] {jobId, timeout / 1000, Configurations.toString(runtimeConfig, true)});
 
       final Configuration driverConfig = DriverConfiguration.CONF
           .set(DriverConfiguration.GLOBAL_LIBRARIES, EnvironmentUtils.getClassLocation(JobDriver.class))
@@ -160,8 +156,8 @@
 
       final Configuration submittedConfiguration = Tang.Factory.getTang()
           .newConfigurationBuilder(driverConfig, commandLineConf).build();
-      DriverLauncher.getLauncher(runtimeConfig)
-          .run(submittedConfiguration, timeout);
+
+      DriverLauncher.getLauncher(runtimeConfig).run(submittedConfiguration, timeout);
 
       LOG.log(Level.INFO, "TIME: Stop Client {0}", jobId);
 
diff --git a/lang/java/reef-examples/src/main/java/org/apache/reef/examples/suspend/Launch.java b/lang/java/reef-examples/src/main/java/org/apache/reef/examples/suspend/Launch.java
index d05aa17..1ea8632 100644
--- a/lang/java/reef-examples/src/main/java/org/apache/reef/examples/suspend/Launch.java
+++ b/lang/java/reef-examples/src/main/java/org/apache/reef/examples/suspend/Launch.java
@@ -21,15 +21,11 @@
 import org.apache.reef.client.ClientConfiguration;
 import org.apache.reef.runtime.local.client.LocalRuntimeConfiguration;
 import org.apache.reef.runtime.yarn.client.YarnClientConfiguration;
-import org.apache.reef.tang.Configuration;
-import org.apache.reef.tang.Injector;
-import org.apache.reef.tang.JavaConfigurationBuilder;
-import org.apache.reef.tang.Tang;
+import org.apache.reef.tang.*;
 import org.apache.reef.tang.annotations.Name;
 import org.apache.reef.tang.annotations.NamedParameter;
 import org.apache.reef.tang.exceptions.BindException;
 import org.apache.reef.tang.exceptions.InjectionException;
-import org.apache.reef.tang.formats.AvroConfigurationSerializer;
 import org.apache.reef.tang.formats.CommandLine;
 
 import java.io.IOException;
@@ -117,10 +113,8 @@
       runtimeConfiguration = YarnClientConfiguration.CONF.build();
     }
 
-    return Tang.Factory.getTang()
-        .newConfigurationBuilder(runtimeConfiguration, clientConfiguration,
-            cloneCommandLineConfiguration(commandLineConf))
-        .build();
+    return Configurations.merge(
+        runtimeConfiguration, clientConfiguration, cloneCommandLineConfiguration(commandLineConf));
   }
 
   /**
@@ -132,8 +126,7 @@
     try {
       final Configuration config = getClientConfiguration(args);
 
-      LOG.log(Level.INFO, "Configuration:\n--\n{0}--",
-          new AvroConfigurationSerializer().toString(config));
+      LOG.log(Level.INFO, "Configuration:\n--\n{0}--", Configurations.toString(config, true));
 
       final Injector injector = Tang.Factory.getTang().newInjector(config);
       final SuspendClient client = injector.getInstance(SuspendClient.class);
diff --git a/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/Configurations.java b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/Configurations.java
index e7578ff..4347852 100644
--- a/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/Configurations.java
+++ b/lang/java/reef-tang/tang/src/main/java/org/apache/reef/tang/Configurations.java
@@ -18,18 +18,22 @@
  */
 package org.apache.reef.tang;
 
+import org.apache.reef.tang.formats.AvroConfigurationSerializer;
+import org.apache.reef.tang.formats.ConfigurationSerializer;
+
 /**
  * Helper class for Configurations.
  */
 public final class Configurations {
 
+  private static final AvroConfigurationSerializer SERIALIZER = new AvroConfigurationSerializer();
+
   /**
    * This is a utility class that isn't meant to be instantiated.
    */
   private Configurations() {
   }
 
-
   /**
    * Merge a set of Configurations.
    *
@@ -56,4 +60,35 @@
     return configurationBuilder.build();
   }
 
+  /**
+   * Get the default configuration serializer.
+   * Currently it is AvroConfigurationSerializer.
+   * Use Tang.toString(...) to produce a human-readable string representation of the config.
+   * @return configuration serializer object.
+   */
+  public static ConfigurationSerializer getDefaultSerializer() {
+    return SERIALIZER;
+  }
+
+  /**
+   * Return human-readable representation of the configuration.
+   * @param config input configuration.
+   * @return a string that contains human-readable representation of the input configuration.
+   */
+  public static String toString(final Configuration config) {
+    return SERIALIZER.toString(config);
+  }
+
+  /**
+   * Return human-readable representation of the configuration.
+   * If prettyPrint is true, try to produce a nicer text layout, if possible.
+   * @param config input configuration.
+   * @param prettyPrint if true, try to produce a nicer text layout, when possible.
+   * Otherwise, use the default options of the serializer.
+   * Default value is false as not all serializers and formats support pretty printing.
+   * @return a string that contains human-readable representation of the input configuration.
+   */
+  public static String toString(final Configuration config, final boolean prettyPrint) {
+    return SERIALIZER.toString(config, prettyPrint);
+  }
 }