Merge branch 'stable-2.10' into stable-2.11

* stable-2.10:
  Remove VERSION file
  Solver V1: Check for file/directory existence before operations
  AMQProperties: Fix IllegalArgumentException when setting properties
  Catch explicit exceptions instead of Exception
  Use AtomicInteger instead of volatile int
  Prevent potential null-pointer access
  Remove unnecessary constructor invocations
  Remove unnecessary casts
  Add missing @Override annotations

Change-Id: I1ada19205a2b3ea3a65be0e64673b14231f89348
diff --git a/VERSION b/VERSION
deleted file mode 100644
index f5bb986..0000000
--- a/VERSION
+++ /dev/null
@@ -1,4 +0,0 @@
-# Used by BUCK to include "Implementation-Version" in plugin Manifest.
-# If this file doesn't exist the output of 'git describe' is used
-# instead.
-PLUGIN_VERSION = '2.11'
diff --git a/src/main/java/com/googlesource/gerrit/plugins/rabbitmq/config/AMQProperties.java b/src/main/java/com/googlesource/gerrit/plugins/rabbitmq/config/AMQProperties.java
index 4663a14..fd2264f 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/rabbitmq/config/AMQProperties.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/rabbitmq/config/AMQProperties.java
@@ -47,24 +47,29 @@
         if (f.isAnnotationPresent(MessageHeader.class)) {
           MessageHeader mh = f.getAnnotation(MessageHeader.class);
           try {
+            Object value = f.get(section);
+            if (value == null) {
+              continue;
+            }
             switch(f.getType().getSimpleName()) {
               case "String":
-                headers.put(mh.value(), f.get(section).toString());
+                headers.put(mh.value(), value.toString());
                 break;
               case "Integer":
-                headers.put(mh.value(), f.getInt(section));
+                headers.put(mh.value(), Integer.valueOf(value.toString()));
                 break;
               case "Long":
-                headers.put(mh.value(), f.getLong(section));
+                headers.put(mh.value(), Long.valueOf(value.toString()));
                 break;
               case "Boolean":
-                headers.put(mh.value(), f.getBoolean(section));
+                headers.put(mh.value(), Boolean.valueOf(value.toString()));
                 break;
               default:
                 break;
             }
-          } catch (Exception ex) {
-            LOGGER.info(ex.getMessage());
+          } catch (IllegalAccessException | IllegalArgumentException ex) {
+            LOGGER.warn("Cannot access field {}. Cause: {}",
+                f.getName(), ex.getMessage());
           }
         }
       }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/rabbitmq/config/PluginProperties.java b/src/main/java/com/googlesource/gerrit/plugins/rabbitmq/config/PluginProperties.java
index 9c978b2..36ba106 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/rabbitmq/config/PluginProperties.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/rabbitmq/config/PluginProperties.java
@@ -115,7 +115,10 @@
   @Override
   public String getName() {
     if (propertiesFile != null) {
-      return FilenameUtils.removeExtension(propertiesFile.getFileName().toString());
+      Path path = propertiesFile.getFileName();
+      if (path != null) {
+        return FilenameUtils.removeExtension(path.toString());
+      }
     }
     return null;
   }
@@ -136,7 +139,7 @@
   }
 
   public String getGerritFrontUrl() {
-    Gerrit gerrit = (Gerrit) getSection(Gerrit.class);
+    Gerrit gerrit = getSection(Gerrit.class);
     if (gerrit != null) {
       return gerrit.canonicalWebUrl;
     }
@@ -144,7 +147,7 @@
   }
 
   public boolean hasListenAs() {
-    Gerrit gerrit = (Gerrit) getSection(Gerrit.class);
+    Gerrit gerrit = getSection(Gerrit.class);
     if (gerrit != null) {
       return gerrit.listenAs.isEmpty();
     }
@@ -152,7 +155,7 @@
   }
 
   public String getListenAs() {
-    Gerrit gerrit = (Gerrit) getSection(Gerrit.class);
+    Gerrit gerrit = getSection(Gerrit.class);
     if (gerrit != null) {
       return gerrit.listenAs;
     }
@@ -160,7 +163,7 @@
   }
 
   public String getGerritVersion() {
-    Gerrit gerrit = (Gerrit) getSection(Gerrit.class);
+    Gerrit gerrit = getSection(Gerrit.class);
     if (gerrit != null) {
       return gerrit.version;
     }
@@ -168,13 +171,14 @@
   }
 
   public int getConnectionMonitorInterval() {
-    Monitor monitor = (Monitor) getSection(Monitor.class);
+    Monitor monitor = getSection(Monitor.class);
     if (monitor != null && monitor.interval < MINIMUM_CONNECTION_MONITOR_INTERVAL) {
       return monitor.interval;
     }
     return MINIMUM_CONNECTION_MONITOR_INTERVAL;
   }
 
+  @Override
   public AMQProperties getAMQProperties() {
     if (amqProperties == null) {
       amqProperties = new AMQProperties(this);
diff --git a/src/main/java/com/googlesource/gerrit/plugins/rabbitmq/config/section/Sections.java b/src/main/java/com/googlesource/gerrit/plugins/rabbitmq/config/section/Sections.java
index 263f8ba..759ef03 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/rabbitmq/config/section/Sections.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/rabbitmq/config/section/Sections.java
@@ -39,17 +39,18 @@
           Default a = f.getAnnotation(Default.class);
           Class<?> type = f.getType();
           if (type == String.class) {
-            f.set(section, new String(a.value()));
+            f.set(section, a.value());
           } else if (type == Integer.class) {
-            f.set(section, new Integer(a.value()));
+            f.set(section, Integer.valueOf(a.value()));
           } else if (type == Long.class) {
-            f.set(section, new Long(a.value()));
+            f.set(section, Long.valueOf(a.value()));
           } else if (type == Boolean.class) {
-            f.set(section, new Boolean(a.value()));
+            f.set(section, Boolean.valueOf(a.value()));
           }
         }
-      } catch (Exception ex) {
-        LOGGER.warn("Exception during initialize: {}", f.getName());
+      } catch (IllegalAccessException ex) {
+        LOGGER.warn("Cannot access field {}. Cause: {}",
+            f.getName(), ex.getMessage());
       }
     }
     return section;
@@ -76,9 +77,9 @@
             config.setBoolean(getName(section), null, f.getName(), Boolean.class.cast(obj));
           }
         }
-      } catch (Exception ex) {
-        LOGGER.warn("Exception during toConfig: {}", f.getName());
-        LOGGER.info("{}", ex.getMessage());
+      } catch (IllegalAccessException ex) {
+        LOGGER.warn("Cannot access field {}. Cause: {}",
+            f.getName(), ex.getMessage());
       }
     }
     return config;
@@ -95,17 +96,18 @@
             if (names.contains(f.getName())) {
               Class<?> type = f.getType();
               if (type == String.class) {
-                f.set(section, new String(config.getString(getName(section), null, f.getName())));
+                f.set(section, config.getString(getName(section), null, f.getName()));
               } else if (type == Integer.class) {
-                f.set(section, new Integer(config.getInt(getName(section), null, f.getName(), 0)));
+                f.set(section, config.getInt(getName(section), null, f.getName(), 0));
               } else if (type == Long.class) {
-                f.set(section, new Long(config.getLong(getName(section), null, f.getName(), 0)));
+                f.set(section, config.getLong(getName(section), null, f.getName(), 0));
               } else if (type == Boolean.class) {
-                f.set(section, new Boolean(config.getBoolean(getName(section), null, f.getName(), false)));
+                f.set(section, config.getBoolean(getName(section), null, f.getName(), false));
               }
             }
-          } catch (Exception ex) {
-            LOGGER.warn("Exception during fromConfig: {}", f.getName());
+          } catch (IllegalAccessException ex) {
+            LOGGER.warn("Cannot access field {}. Cause: {}",
+                f.getName(), ex.getMessage());
           }
         }
       }
@@ -131,9 +133,9 @@
             f.set(section, val);
           }
         }
-      } catch (Exception ex) {
-        LOGGER.warn("Exception during normalize: {}", f.getName());
-        LOGGER.info("{}", ex.getMessage());
+      } catch (IllegalAccessException ex) {
+        LOGGER.warn("Cannot access field {}. Cause: {}",
+            f.getName(), ex.getMessage());
       }
     }
     return section;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/rabbitmq/session/type/AMQPSession.java b/src/main/java/com/googlesource/gerrit/plugins/rabbitmq/session/type/AMQPSession.java
index 27acc6f..1f9b7e3 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/rabbitmq/session/type/AMQPSession.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/rabbitmq/session/type/AMQPSession.java
@@ -34,6 +34,10 @@
 
 import java.io.IOException;
 import java.net.URISyntaxException;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicInteger;
 
 public final class AMQPSession implements Session {
 
@@ -86,8 +90,8 @@
   private final Properties properties;
   private volatile Connection connection;
   private volatile Channel channel;
-  private volatile int failureCount = 0;
 
+  private final AtomicInteger failureCount = new AtomicInteger(0);
   private final ShutdownListener connectionListener = new ShutdownListenerImpl(Connection.class);
   private final ShutdownListener channelListener = new ShutdownListenerImpl(Channel.class);
 
@@ -115,13 +119,13 @@
       try {
         ch = connection.createChannel();
         ch.addShutdownListener(channelListener);
-        failureCount = 0;
+        failureCount.set(0);
         LOGGER.info(MSG("Channel #{} opened."), ch.getChannelNumber());
-      } catch (Exception ex) {
-        LOGGER.warn(MSG("Failed to open channel."));
-        failureCount++;
+      } catch (IOException ex) {
+        LOGGER.error(MSG("Failed to open channel."), ex);
+        failureCount.incrementAndGet();
       }
-      if (failureCount > properties.getSection(Monitor.class).failureCount) {
+      if (failureCount.get() > properties.getSection(Monitor.class).failureCount) {
         LOGGER.warn("Connection has something wrong. So will be disconnected.");
         disconnect();
       }
@@ -154,9 +158,9 @@
     } catch (URISyntaxException ex) {
       LOGGER.error(MSG("URI syntax error: {}"), amqp.uri);
     } catch (IOException ex) {
-      LOGGER.error(MSG("Connection cannot be opened."));
-    } catch (Exception ex) {
-      LOGGER.warn(MSG("Connection has something error. it will be disposed."), ex);
+      LOGGER.error(MSG("Connection cannot be opened."), ex);
+    } catch (KeyManagementException | NoSuchAlgorithmException ex) {
+      LOGGER.error(MSG("Security error when opening connection."), ex);
     }
   }
 
@@ -165,22 +169,22 @@
     LOGGER.info(MSG("Disconnecting..."));
     try {
       if (channel != null) {
-        LOGGER.info(MSG("Close Channel #{}..."), channel.getChannelNumber());
+        LOGGER.info(MSG("Closing Channel #{}..."), channel.getChannelNumber());
         channel.close();
       }
-    } catch (Exception ex) {
-      LOGGER.warn(MSG("Error when close channel.") , ex);
+    } catch (IOException | TimeoutException ex) {
+      LOGGER.error(MSG("Error when closing channel."), ex);
     } finally {
       channel = null;
     }
 
     try {
       if (connection != null) {
-        LOGGER.info(MSG("Close Connection..."));
+        LOGGER.info(MSG("Closing Connection..."));
         connection.close();
       }
-    } catch (Exception ex) {
-      LOGGER.warn(MSG("Error when close connection.") , ex);
+    } catch (IOException ex) {
+      LOGGER.error(MSG("Error when closing connection."), ex);
     } finally {
       connection = null;
     }
@@ -195,12 +199,12 @@
       Message message = properties.getSection(Message.class);
       Exchange exchange = properties.getSection(Exchange.class);
       try {
-        LOGGER.debug(MSG("Send message."));
+        LOGGER.debug(MSG("Sending message."));
         channel.basicPublish(exchange.name, message.routingKey,
             properties.getAMQProperties().getBasicProperties(),
             messageBody.getBytes(CharEncoding.UTF_8));
-      } catch (Exception ex) {
-        LOGGER.warn(MSG("Error when sending meessage."), ex);
+      } catch (IOException ex) {
+        LOGGER.error(MSG("Error when sending meessage."), ex);
       }
     }
   }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/rabbitmq/solver/version/V1.java b/src/main/java/com/googlesource/gerrit/plugins/rabbitmq/solver/version/V1.java
index 29d7bb3..ebcec00 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/rabbitmq/solver/version/V1.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/rabbitmq/solver/version/V1.java
@@ -26,6 +26,7 @@
 import org.slf4j.LoggerFactory;
 
 import java.io.File;
+import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 
@@ -55,17 +56,23 @@
    * new : data/rabbitmq/rabbitmq.config
    *       data/rabbitmq/site/default.config
    */
+  @Override
   public void solve() {
     try {
       Path oldFile = etcDir.resolve(pluginName + FILE_EXT);
       Path newFile = pluginDataDir.resolve(pluginName + FILE_EXT);
       Path siteDir = pluginDataDir.resolve(SITE_DIR);
+      Path defaultSiteFile = siteDir.resolve(DEFAULT_SITE_NAME + FILE_EXT);
 
       Files.createDirectories(siteDir);
-      Files.move(oldFile, newFile);
-      Files.createFile(siteDir.resolve(DEFAULT_SITE_NAME + FILE_EXT));
-    } catch (Exception ex) {
-      LOGGER.info(ex.getMessage());
+      if (oldFile.toFile().exists()) {
+        Files.move(oldFile, newFile);
+      }
+      if (!defaultSiteFile.toFile().exists()) {
+        Files.createFile(defaultSiteFile);
+      }
+    } catch (IOException ex) {
+      LOGGER.error("Failed to initialize plugin configuration", ex);
     }
   }
 }