azkaban-aplcache

move singleton to classes's annotations (#1286) * move singleton

7/25/2017 6:40:06 PM

Details

diff --git a/azkaban-common/src/main/java/azkaban/AzkabanCommonModule.java b/azkaban-common/src/main/java/azkaban/AzkabanCommonModule.java
index f528556..71fb6b9 100644
--- a/azkaban-common/src/main/java/azkaban/AzkabanCommonModule.java
+++ b/azkaban-common/src/main/java/azkaban/AzkabanCommonModule.java
@@ -25,7 +25,6 @@ import azkaban.db.DatabaseOperator;
 import azkaban.db.DatabaseOperatorImpl;
 import azkaban.db.H2FileDataSource;
 import azkaban.db.MySQLDataSource;
-import azkaban.executor.AlerterHolder;
 import azkaban.executor.ExecutorLoader;
 import azkaban.executor.ExecutorManager;
 import azkaban.executor.JdbcExecutorLoader;
@@ -76,16 +75,13 @@ public class AzkabanCommonModule extends AbstractModule {
 
   @Override
   protected void configure() {
-    bind(ExecutorLoader.class).to(JdbcExecutorLoader.class).in(Scopes.SINGLETON);
     bind(Props.class).toInstance(this.config.getProps());
-    bind(Storage.class).to(resolveStorageClassType()).in(Scopes.SINGLETON);
-    bind(HdfsAuth.class).in(Scopes.SINGLETON);
-    bind(DatabaseOperator.class).to(DatabaseOperatorImpl.class).in(Scopes.SINGLETON);
-    bind(TriggerLoader.class).to(JdbcTriggerImpl.class).in(Scopes.SINGLETON);
-    bind(ProjectLoader.class).to(JdbcProjectImpl.class).in(Scopes.SINGLETON);
+    bind(Storage.class).to(resolveStorageClassType());
+    bind(DatabaseOperator.class).to(DatabaseOperatorImpl.class);
+    bind(TriggerLoader.class).to(JdbcTriggerImpl.class);
+    bind(ProjectLoader.class).to(JdbcProjectImpl.class);
     bind(DataSource.class).to(AzkabanDataSource.class);
-    bind(ExecutorManager.class).in(Scopes.SINGLETON);
-    bind(AlerterHolder.class).in(Scopes.SINGLETON);
+    bind(ExecutorLoader.class).to(JdbcExecutorLoader.class);
     bind(MetricRegistry.class).in(Scopes.SINGLETON);
   }
 
diff --git a/azkaban-common/src/main/java/azkaban/executor/AlerterHolder.java b/azkaban-common/src/main/java/azkaban/executor/AlerterHolder.java
index 9c3d799..95c2347 100644
--- a/azkaban-common/src/main/java/azkaban/executor/AlerterHolder.java
+++ b/azkaban-common/src/main/java/azkaban/executor/AlerterHolder.java
@@ -23,6 +23,7 @@ import azkaban.utils.FileIOUtils;
 import azkaban.utils.Props;
 import azkaban.utils.PropsUtils;
 import com.google.inject.Inject;
+import com.google.inject.Singleton;
 import java.io.File;
 import java.lang.reflect.Constructor;
 import java.net.MalformedURLException;
@@ -36,6 +37,7 @@ import java.util.Map;
 import org.apache.log4j.Logger;
 
 
+@Singleton
 public class AlerterHolder {
 
   private static final Logger logger = Logger.getLogger(AlerterHolder.class);
diff --git a/azkaban-common/src/main/java/azkaban/executor/ExecutorManager.java b/azkaban-common/src/main/java/azkaban/executor/ExecutorManager.java
index 9c0a032..e5328be 100644
--- a/azkaban-common/src/main/java/azkaban/executor/ExecutorManager.java
+++ b/azkaban-common/src/main/java/azkaban/executor/ExecutorManager.java
@@ -21,6 +21,7 @@ import azkaban.metrics.CommonMetrics;
 import azkaban.utils.FlowUtils;
 import com.google.common.collect.Lists;
 import com.google.inject.Inject;
+import com.google.inject.Singleton;
 import java.io.File;
 import java.io.IOException;
 import java.lang.Thread.State;
@@ -68,6 +69,7 @@ import azkaban.utils.Props;
  * Executor manager used to manage the client side job.
  *
  */
+@Singleton
 public class ExecutorManager extends EventHandler implements
     ExecutorManagerAdapter {
   static final String AZKABAN_EXECUTOR_SELECTOR_FILTERS =
diff --git a/azkaban-common/src/main/java/azkaban/executor/JdbcExecutorLoader.java b/azkaban-common/src/main/java/azkaban/executor/JdbcExecutorLoader.java
index 2f7b9cf..0e572a7 100644
--- a/azkaban-common/src/main/java/azkaban/executor/JdbcExecutorLoader.java
+++ b/azkaban-common/src/main/java/azkaban/executor/JdbcExecutorLoader.java
@@ -18,6 +18,7 @@ package azkaban.executor;
 
 import azkaban.metrics.CommonMetrics;
 import com.google.inject.Inject;
+import com.google.inject.Singleton;
 import java.io.BufferedInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
@@ -54,6 +55,7 @@ import azkaban.utils.Pair;
 import azkaban.utils.Props;
 import azkaban.utils.PropsUtils;
 
+@Singleton
 public class JdbcExecutorLoader extends AbstractJdbcLoader implements
     ExecutorLoader {
   private static final Logger logger = Logger
diff --git a/azkaban-common/src/main/java/azkaban/project/JdbcProjectImpl.java b/azkaban-common/src/main/java/azkaban/project/JdbcProjectImpl.java
index b212a92..8e28396 100644
--- a/azkaban-common/src/main/java/azkaban/project/JdbcProjectImpl.java
+++ b/azkaban-common/src/main/java/azkaban/project/JdbcProjectImpl.java
@@ -41,6 +41,7 @@ import azkaban.utils.PropsUtils;
 import azkaban.utils.Triple;
 import com.google.common.io.Files;
 import com.google.inject.Inject;
+import com.google.inject.Singleton;
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
 import java.io.File;
@@ -62,6 +63,7 @@ import org.apache.log4j.Logger;
  * TODO kunkun-tang: This class is too long. In future, we should split {@link ProjectLoader} interface
  * and have multiple short class implementations.
  */
+@Singleton
 public class JdbcProjectImpl implements ProjectLoader {
   private static final Logger logger = Logger.getLogger(JdbcProjectImpl.class);
 
diff --git a/azkaban-common/src/main/java/azkaban/storage/DatabaseStorage.java b/azkaban-common/src/main/java/azkaban/storage/DatabaseStorage.java
index 6622da0..7c6b15e 100644
--- a/azkaban-common/src/main/java/azkaban/storage/DatabaseStorage.java
+++ b/azkaban-common/src/main/java/azkaban/storage/DatabaseStorage.java
@@ -21,6 +21,7 @@ import azkaban.project.ProjectFileHandler;
 import azkaban.project.ProjectLoader;
 import azkaban.spi.Storage;
 import azkaban.spi.StorageMetadata;
+import com.google.inject.Singleton;
 import java.io.File;
 import java.io.InputStream;
 import javax.inject.Inject;
@@ -32,6 +33,7 @@ import javax.inject.Inject;
  * This class helps in storing projects in the DB itself. This is intended to be the default since
  * it is the current behavior of Azkaban.
  */
+@Singleton
 public class DatabaseStorage implements Storage {
 
   private final ProjectLoader projectLoader;
diff --git a/azkaban-common/src/main/java/azkaban/storage/HdfsAuth.java b/azkaban-common/src/main/java/azkaban/storage/HdfsAuth.java
index 6a56b50..b9a666d 100644
--- a/azkaban-common/src/main/java/azkaban/storage/HdfsAuth.java
+++ b/azkaban-common/src/main/java/azkaban/storage/HdfsAuth.java
@@ -24,6 +24,7 @@ import static java.util.Objects.requireNonNull;
 import azkaban.spi.AzkabanException;
 import azkaban.utils.Props;
 import com.google.inject.Inject;
+import com.google.inject.Singleton;
 import java.io.IOException;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.security.UserGroupInformation;
@@ -34,6 +35,7 @@ import org.apache.log4j.Logger;
  * This class helps in HDFS authorization and is a wrapper over Hadoop's {@link
  * UserGroupInformation} class.
  */
+@Singleton
 public class HdfsAuth {
 
   private static final Logger log = Logger.getLogger(HdfsAuth.class);
diff --git a/azkaban-common/src/main/java/azkaban/storage/HdfsStorage.java b/azkaban-common/src/main/java/azkaban/storage/HdfsStorage.java
index d2d374f..b0ef27e 100644
--- a/azkaban-common/src/main/java/azkaban/storage/HdfsStorage.java
+++ b/azkaban-common/src/main/java/azkaban/storage/HdfsStorage.java
@@ -25,6 +25,7 @@ import azkaban.spi.Storage;
 import azkaban.spi.StorageException;
 import azkaban.spi.StorageMetadata;
 import com.google.inject.Inject;
+import com.google.inject.Singleton;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
@@ -35,6 +36,7 @@ import org.apache.hadoop.fs.Path;
 import org.apache.log4j.Logger;
 
 
+@Singleton
 public class HdfsStorage implements Storage {
 
   private static final Logger log = Logger.getLogger(HdfsStorage.class);
diff --git a/azkaban-common/src/main/java/azkaban/storage/LocalStorage.java b/azkaban-common/src/main/java/azkaban/storage/LocalStorage.java
index 21adef5..56d4143 100644
--- a/azkaban-common/src/main/java/azkaban/storage/LocalStorage.java
+++ b/azkaban-common/src/main/java/azkaban/storage/LocalStorage.java
@@ -25,6 +25,7 @@ import azkaban.spi.StorageException;
 import azkaban.spi.StorageMetadata;
 import azkaban.utils.FileIOUtils;
 import com.google.inject.Inject;
+import com.google.inject.Singleton;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
@@ -34,6 +35,7 @@ import org.apache.commons.io.FileUtils;
 import org.apache.log4j.Logger;
 
 
+@Singleton
 public class LocalStorage implements Storage {
 
   private static final Logger log = Logger.getLogger(LocalStorage.class);
diff --git a/azkaban-common/src/main/java/azkaban/trigger/JdbcTriggerImpl.java b/azkaban-common/src/main/java/azkaban/trigger/JdbcTriggerImpl.java
index 1d25215..aa442bd 100644
--- a/azkaban-common/src/main/java/azkaban/trigger/JdbcTriggerImpl.java
+++ b/azkaban-common/src/main/java/azkaban/trigger/JdbcTriggerImpl.java
@@ -22,6 +22,7 @@ import azkaban.db.SQLTransaction;
 import azkaban.utils.GZIPUtils;
 import azkaban.utils.JSONUtils;
 import com.google.inject.Inject;
+import com.google.inject.Singleton;
 import java.io.IOException;
 import java.sql.ResultSet;
 import java.sql.SQLException;
@@ -33,6 +34,7 @@ import org.apache.log4j.Logger;
 import org.joda.time.DateTime;
 
 
+@Singleton
 public class JdbcTriggerImpl implements TriggerLoader {
 
   private static final String TRIGGER_TABLE_NAME = "triggers";
diff --git a/azkaban-common/src/test/java/azkaban/ServiceProviderTest.java b/azkaban-common/src/test/java/azkaban/ServiceProviderTest.java
index ac3d6bd..d401660 100644
--- a/azkaban-common/src/test/java/azkaban/ServiceProviderTest.java
+++ b/azkaban-common/src/test/java/azkaban/ServiceProviderTest.java
@@ -18,7 +18,7 @@
 package azkaban;
 
 import static azkaban.ServiceProvider.SERVICE_PROVIDER;
-import static org.junit.Assert.assertNotNull;
+import static org.assertj.core.api.Assertions.assertThat;
 
 import azkaban.db.DatabaseOperator;
 import azkaban.project.JdbcProjectImpl;
@@ -39,6 +39,15 @@ public class ServiceProviderTest {
 
   public static final String AZKABAN_LOCAL_TEST_STORAGE = "AZKABAN_LOCAL_TEST_STORAGE";
 
+  // Test if one class is singletonly guiced. could be called by
+  // AZ Common, Web, or Exec Modules.
+  public static void assertSingleton(final Class azkabanClass, final Injector injector) {
+    final Object azkabanObj1 = injector.getInstance(azkabanClass);
+    final Object azkabanObj2 = injector.getInstance(azkabanClass);
+    // Note: isSameAs is quite different from isEqualto in AssertJ
+    assertThat(azkabanObj1).isSameAs(azkabanObj2).isNotNull();
+  }
+
   @After
   public void tearDown() throws Exception {
     FileUtils.deleteDirectory(new File(AZKABAN_LOCAL_TEST_STORAGE));
@@ -58,11 +67,11 @@ public class ServiceProviderTest {
     SERVICE_PROVIDER.unsetInjector();
     SERVICE_PROVIDER.setInjector(injector);
 
-    assertNotNull(SERVICE_PROVIDER.getInstance(JdbcProjectImpl.class));
-    assertNotNull(SERVICE_PROVIDER.getInstance(StorageManager.class));
-    assertNotNull(SERVICE_PROVIDER.getInstance(DatabaseStorage.class));
-    assertNotNull(SERVICE_PROVIDER.getInstance(LocalStorage.class));
-    assertNotNull(SERVICE_PROVIDER.getInstance(Storage.class));
-    assertNotNull(SERVICE_PROVIDER.getInstance(DatabaseOperator.class));
+    assertThat(injector.getInstance(JdbcProjectImpl.class)).isNotNull();
+    assertThat(injector.getInstance(StorageManager.class)).isNotNull();
+    assertThat(injector.getInstance(DatabaseStorage.class)).isNotNull();
+    assertThat(injector.getInstance(LocalStorage.class)).isNotNull();
+    assertThat(injector.getInstance(Storage.class)).isNotNull();
+    assertThat(injector.getInstance(DatabaseOperator.class)).isNotNull();
   }
 }
diff --git a/azkaban-db/src/main/java/azkaban/db/DatabaseOperatorImpl.java b/azkaban-db/src/main/java/azkaban/db/DatabaseOperatorImpl.java
index 556a534..9a89eda 100644
--- a/azkaban-db/src/main/java/azkaban/db/DatabaseOperatorImpl.java
+++ b/azkaban-db/src/main/java/azkaban/db/DatabaseOperatorImpl.java
@@ -18,6 +18,7 @@ package azkaban.db;
 import static java.util.Objects.requireNonNull;
 
 import com.google.inject.Inject;
+import com.google.inject.Singleton;
 import java.sql.Connection;
 import java.sql.SQLException;
 import org.apache.commons.dbutils.DbUtils;
@@ -28,6 +29,7 @@ import org.apache.log4j.Logger;
 /**
  * Implement AZ DB related operations. This class is thread safe.
  */
+@Singleton
 public class DatabaseOperatorImpl implements DatabaseOperator {
 
   private static final Logger logger = Logger.getLogger(DatabaseOperatorImpl.class);
diff --git a/azkaban-exec-server/src/main/java/azkaban/execapp/AzkabanExecServerModule.java b/azkaban-exec-server/src/main/java/azkaban/execapp/AzkabanExecServerModule.java
index 1688705..fc47a15 100644
--- a/azkaban-exec-server/src/main/java/azkaban/execapp/AzkabanExecServerModule.java
+++ b/azkaban-exec-server/src/main/java/azkaban/execapp/AzkabanExecServerModule.java
@@ -32,7 +32,7 @@ public class AzkabanExecServerModule extends AbstractModule {
 
   @Override
   protected void configure() {
-    bind(ExecutorLoader.class).to(JdbcExecutorLoader.class).in(Scopes.SINGLETON);
+    bind(ExecutorLoader.class).to(JdbcExecutorLoader.class);
     bind(AzkabanExecutorServer.class).in(Scopes.SINGLETON);
     bind(TriggerManager.class).in(Scopes.SINGLETON);
     bind(FlowRunnerManager.class).in(Scopes.SINGLETON);
diff --git a/azkaban-web-server/src/test/java/azkaban/webapp/AzkabanWebServerTest.java b/azkaban-web-server/src/test/java/azkaban/webapp/AzkabanWebServerTest.java
index 4f17833..a4ef1a0 100644
--- a/azkaban-web-server/src/test/java/azkaban/webapp/AzkabanWebServerTest.java
+++ b/azkaban-web-server/src/test/java/azkaban/webapp/AzkabanWebServerTest.java
@@ -18,17 +18,23 @@
 package azkaban.webapp;
 
 import static azkaban.ServiceProvider.SERVICE_PROVIDER;
+import static azkaban.ServiceProviderTest.assertSingleton;
 import static azkaban.executor.ExecutorManager.AZKABAN_USE_MULTIPLE_EXECUTORS;
 import static java.util.Objects.requireNonNull;
 import static org.apache.commons.io.FileUtils.deleteQuietly;
 import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
 
 import azkaban.AzkabanCommonModule;
 import azkaban.database.AzkabanDatabaseSetup;
 import azkaban.database.AzkabanDatabaseUpdater;
+import azkaban.db.DatabaseOperator;
 import azkaban.executor.Executor;
 import azkaban.executor.ExecutorLoader;
+import azkaban.executor.ExecutorManager;
+import azkaban.project.ProjectLoader;
+import azkaban.project.ProjectManager;
+import azkaban.spi.Storage;
+import azkaban.trigger.TriggerLoader;
 import azkaban.trigger.TriggerManager;
 import azkaban.utils.Props;
 import com.google.inject.Guice;
@@ -115,9 +121,15 @@ public class AzkabanWebServerTest {
     assertNotNull(injector.getInstance(AzkabanWebServer.class));
 
     //Test if triggermanager is singletonly guiced. If not, the below test will fail.
-    final TriggerManager triggerManager1 = requireNonNull(injector.getInstance(TriggerManager.class));
-    final TriggerManager triggerManager2 = requireNonNull(injector.getInstance(TriggerManager.class));
-    assertTrue(triggerManager1 == triggerManager2);
+    assertSingleton(ExecutorLoader.class, injector);
+    assertSingleton(ExecutorManager.class, injector);
+    assertSingleton(ProjectLoader.class, injector);
+    assertSingleton(ProjectManager.class, injector);
+    assertSingleton(Storage.class, injector);
+    assertSingleton(DatabaseOperator.class, injector);
+    assertSingleton(TriggerLoader.class, injector);
+    assertSingleton(TriggerManager.class, injector);
+
     SERVICE_PROVIDER.unsetInjector();
   }
 }