Merge branch 'stable-2.12' into stable-2.13

* stable-2.12:
  Do not log exception stack trace when project not in database
  Fix JDBC connection
  Fix configuration documentation formatting
  Remove source_under_test to comply with new BUCK version

Change-Id: I4d4888aed5bb5f787c9c881c8b905b2037395512
diff --git a/src/main/java/com/ericsson/gerrit/plugins/eventslog/EventsLogConfig.java b/src/main/java/com/ericsson/gerrit/plugins/eventslog/EventsLogConfig.java
index 29e7299..997f86d 100644
--- a/src/main/java/com/ericsson/gerrit/plugins/eventslog/EventsLogConfig.java
+++ b/src/main/java/com/ericsson/gerrit/plugins/eventslog/EventsLogConfig.java
@@ -14,6 +14,7 @@
 
 package com.ericsson.gerrit.plugins.eventslog;
 
+import com.google.common.base.Joiner;
 import com.google.gerrit.extensions.annotations.PluginName;
 import com.google.gerrit.server.config.PluginConfig;
 import com.google.gerrit.server.config.PluginConfigFactory;
@@ -81,12 +82,16 @@
     storeUrl = cfg.getString(CONFIG_URL, DEFAULT_URL);
     localStorePath = Paths.get(cfg.getString(CONFIG_LOCAL_PATH,
         defaultLocalPath));
-    urlOptions = cfg.getString(CONFIG_URL_OPTIONS, "");
+    urlOptions = concatenate(cfg.getStringList(CONFIG_URL_OPTIONS));
     storeUsername = cfg.getString(CONFIG_USERNAME);
     storePassword = cfg.getString(CONFIG_PASSWORD);
     evictIdleTime = cfg.getInt(CONFIG_EVICT_IDLE_TIME, DEFAULT_EVICT_IDLE_TIME);
   }
 
+  private String concatenate(String[] stringList) {
+    return Joiner.on(";").join(stringList);
+  }
+
   public int getMaxAge() {
     return maxAge;
   }
diff --git a/src/main/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLClient.java b/src/main/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLClient.java
index e4ccd9e..d4ae595 100644
--- a/src/main/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLClient.java
+++ b/src/main/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLClient.java
@@ -57,7 +57,8 @@
   SQLClient(String storeDriver, String storeUrl, String urlOptions) {
     ds = new BasicDataSource();
     ds.setDriverClassName(storeDriver);
-    ds.setUrl(storeUrl + TABLE_NAME + ";" + urlOptions);
+    ds.setUrl(storeUrl);
+    ds.setConnectionProperties(urlOptions);
     gson = new GsonBuilder()
         .registerTypeAdapter(Supplier.class, new SupplierSerializer()).create();
   }
@@ -110,8 +111,7 @@
   boolean dbExists() throws SQLException {
     try (Connection conn = ds.getConnection();
         ResultSet tables =
-            conn.getMetaData().getTables(null, null, TABLE_NAME.toUpperCase(),
-                null)) {
+            conn.getMetaData().getTables(null, null, TABLE_NAME, null)) {
       return tables.next();
     }
   }
diff --git a/src/main/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLModule.java b/src/main/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLModule.java
index 2896942..e8f0559 100644
--- a/src/main/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLModule.java
+++ b/src/main/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLModule.java
@@ -54,8 +54,10 @@
   @Singleton
   @LocalEventsDb
   SQLClient provideLocalSqlClient(EventsLogConfig cfg) {
+    String path = cfg.getLocalStorePath().toString();
+    path = path.endsWith("/") ? path : path + "/";
     SQLClient sqlClient = new SQLClient(cfg.getLocalStoreDriver(),
-        H2_DB_PREFIX + cfg.getLocalStorePath() + "/", cfg.getUrlOptions());
+        H2_DB_PREFIX + path + SQLTable.TABLE_NAME, cfg.getUrlOptions());
     sqlClient.setEvictIdleTime(cfg.getEvictIdleTime());
     return sqlClient;
   }
diff --git a/src/main/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLStore.java b/src/main/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLStore.java
index 5997dfb..9be05fd 100644
--- a/src/main/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLStore.java
+++ b/src/main/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLStore.java
@@ -125,7 +125,7 @@
         }
       } catch (NoSuchProjectException e) {
         log.warn("Database contains a non-existing project, " + projectName
-            + ", removing project from database", e);
+            + ", removing project from database");
         eventsDb.removeProjectEvents(projectName);
       } catch (IOException e) {
         log.warn("Cannot get project visibility info for " + projectName
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md
index 69b7a46..749c600 100644
--- a/src/main/resources/Documentation/config.md
+++ b/src/main/resources/Documentation/config.md
@@ -4,12 +4,15 @@
 File 'gerrit.config'
 --------------------
 
+```
   [plugin "@PLUGIN@"]
     maxAge = 20
     returnLimit = 10000
     storeUrl = jdbc:h2:~/gerrit/db/
-    urlOptions = DB_CLOSE_DELAY=10
+    urlOptions = loglevel=INFO
+    urlOptions = logUnclosedConnections=true
     copyLocal = true
+```
 
 plugin.@PLUGIN@.maxAge
 :    Specify the maximum allowed age in days of the entries in the database.
@@ -41,7 +44,10 @@
      also be defined in secure.config.
 
 plugin.@PLUGIN@.urlOptions
-:    Options to append to the database url.
+:    Options to append to the database url. Each option should be specified in a
+     separate line using the option=value format. For example:
+       urlOptions = loglevel=INFO
+       urlOptions = logUnclosedConnections=true
 
 plugin.@PLUGIN@.maxTries
 :    Maximum number of times the plugin should attempt to store the event if a
@@ -68,4 +74,4 @@
 plugin.@PLUGIN@.evictIdleTime
 :    Interval of time in milliseconds after which an idle database connection is
      evicted from the connection pool. When not specified, the default value is
-     set to 60000ms.
\ No newline at end of file
+     set to 60000ms.
diff --git a/src/test/java/com/ericsson/gerrit/plugins/eventslog/EventsLogConfigTest.java b/src/test/java/com/ericsson/gerrit/plugins/eventslog/EventsLogConfigTest.java
index 461f197..d6ae725 100644
--- a/src/test/java/com/ericsson/gerrit/plugins/eventslog/EventsLogConfigTest.java
+++ b/src/test/java/com/ericsson/gerrit/plugins/eventslog/EventsLogConfigTest.java
@@ -38,6 +38,7 @@
 import static com.google.common.truth.Truth.assertThat;
 import static org.easymock.EasyMock.expect;
 
+import com.google.common.base.Joiner;
 import com.google.gerrit.server.config.PluginConfig;
 import com.google.gerrit.server.config.PluginConfigFactory;
 import com.google.gerrit.server.config.SitePaths;
@@ -60,6 +61,7 @@
   private EasyMockSupport easyMock;
   private String defaultLocalStorePath;
   private String localStorePath;
+  private String [] urlOptions = new String[]{"a=b", "c=d"};
 
   private static final int CUSTOM_EVICT_IDLE_TIME = 10000;
 
@@ -88,7 +90,7 @@
     expect(configMock.getString(CONFIG_DRIVER, DEFAULT_DRIVER)).andReturn(DEFAULT_DRIVER);
     expect(configMock.getString(CONFIG_URL, DEFAULT_URL)).andReturn(DEFAULT_URL);
     expect(configMock.getString(CONFIG_LOCAL_PATH, defaultLocalStorePath)).andReturn(defaultLocalStorePath);
-    expect(configMock.getString(CONFIG_URL_OPTIONS, "")).andReturn("");
+    expect(configMock.getStringList(CONFIG_URL_OPTIONS)).andReturn(new String[0]);
     expect(configMock.getString(CONFIG_USERNAME)).andReturn(null);
     expect(configMock.getString(CONFIG_PASSWORD)).andReturn(null);
     expect(configMock.getInt(CONFIG_EVICT_IDLE_TIME, DEFAULT_EVICT_IDLE_TIME)).andReturn(DEFAULT_EVICT_IDLE_TIME);
@@ -107,7 +109,7 @@
     expect(configMock.getString(CONFIG_DRIVER, DEFAULT_DRIVER)).andReturn("org.h2.Driver2");
     expect(configMock.getString(CONFIG_URL, DEFAULT_URL)).andReturn("jdbc:h2:~/gerrit/db");
     expect(configMock.getString(CONFIG_LOCAL_PATH, defaultLocalStorePath)).andReturn(localStorePath);
-    expect(configMock.getString(CONFIG_URL_OPTIONS, "")).andReturn("DB_CLOSE_DELAY=10");
+    expect(configMock.getStringList(CONFIG_URL_OPTIONS)).andReturn(urlOptions);
     expect(configMock.getString(CONFIG_USERNAME)).andReturn("testUsername");
     expect(configMock.getString(CONFIG_PASSWORD)).andReturn("testPassword");
     expect(configMock.getInt(CONFIG_EVICT_IDLE_TIME, DEFAULT_EVICT_IDLE_TIME)).andReturn(CUSTOM_EVICT_IDLE_TIME);
@@ -149,7 +151,7 @@
     assertThat(config.getLocalStorePath().toString() + "/").isEqualTo(localStorePath);
     assertThat(config.getStoreDriver()).isEqualTo("org.h2.Driver2");
     assertThat(config.getStoreUrl()).isEqualTo("jdbc:h2:~/gerrit/db");
-    assertThat(config.getUrlOptions()).isEqualTo("DB_CLOSE_DELAY=10");
+    assertThat(config.getUrlOptions()).isEqualTo(Joiner.on(";").join(urlOptions));
     assertThat(config.getStoreUsername()).isEqualTo("testUsername");
     assertThat(config.getStorePassword()).isEqualTo("testPassword");
     assertThat(config.getEvictIdleTime()).isEqualTo(CUSTOM_EVICT_IDLE_TIME);
diff --git a/src/test/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLStoreTest.java b/src/test/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLStoreTest.java
index 88b2bb7..d67ebd2 100644
--- a/src/test/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLStoreTest.java
+++ b/src/test/java/com/ericsson/gerrit/plugins/eventslog/sql/SQLStoreTest.java
@@ -58,10 +58,10 @@
 
 public class SQLStoreTest {
   private static final Logger log = LoggerFactory.getLogger(SQLStoreTest.class);
-  private static final String TEST_URL = "jdbc:h2:mem:";
+  private static final String TEST_URL = "jdbc:h2:mem:" + TABLE_NAME;
   private static final String TEST_LOCAL_URL = "jdbc:h2:mem:test:";
   private static final String TEST_DRIVER = "org.h2.Driver";
-  private static final String TEST_OPTIONS = "DB_CLOSE_DELAY=-1";
+  private static final String TEST_OPTIONS = "DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false";
   private static final String TERM_CONN_MSG = "terminating connection";
   private static final String MSG = "message";
   private static final String GENERIC_QUERY = "SELECT * FROM " + TABLE_NAME;
@@ -75,7 +75,7 @@
   private SQLStore store;
   private ScheduledThreadPoolExecutor poolMock;
 
-  private String path = TEST_URL + TABLE_NAME + ";" + TEST_OPTIONS;
+  private String path = TEST_URL + ";" + TEST_OPTIONS;
   private Connection conn;
   private Statement stat;
   private List<SQLEntry> results;