Fix FindBugs warnings in sal-akk-raft 05/46905/8
authorTom Pantelis <tpanteli@brocade.com>
Thu, 13 Oct 2016 15:58:23 +0000 (11:58 -0400)
committerTom Pantelis <tpanteli@brocade.com>
Wed, 26 Oct 2016 16:29:55 +0000 (16:29 +0000)
Fixed FindBugs warnings in sal-akk-raft and enabled the maven plugin to
run and fail the build on violations. Some warnngs were suppressed with
justification provided.

Change-Id: I96b4bb58e6f5a6c3d3d14dadb9567df58ef5905f
Signed-off-by: Tom Pantelis <tpanteli@brocade.com>
opendaylight/md-sal/sal-akka-raft/pom.xml
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActorRecoverySupport.java
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/Snapshot.java
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/base/messages/CaptureSnapshotReply.java
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/client/messages/GetSnapshotReply.java
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/AppendEntries.java
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/messages/InstallSnapshot.java
opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/persisted/ServerConfigurationPayload.java
opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/SnapshotTrackerTest.java
opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/utils/MessageCollectorActor.java

index c4943cd2723e1161ba774188cb5743d1c9413e15..6f106159fa23a51d2a05424bad1cd15e02d6b98c 100644 (file)
           <propertyExpansion>checkstyle.violationSeverity=error</propertyExpansion>
         </configuration>
       </plugin>
-
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>findbugs-maven-plugin</artifactId>
+        <configuration>
+          <failOnError>true</failOnError>
+        </configuration>
+      </plugin>
     </plugins>
   </build>
   <scm>
index f0a7066d85eaba13ddd11d6f79876858c0395f58..5e4e6571a10d3d1f998796849a9be7486d86de75 100644 (file)
@@ -11,6 +11,7 @@ import akka.persistence.RecoveryCompleted;
 import akka.persistence.SnapshotOffer;
 import com.google.common.base.Stopwatch;
 import java.io.ByteArrayInputStream;
+import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.util.Collections;
 import org.opendaylight.controller.cluster.PersistentDataProvider;
@@ -96,7 +97,7 @@ class RaftActorRecoverySupport {
             log.debug("{}: Deserialized restore snapshot: {}", context.getId(), snapshot);
 
             context.getSnapshotManager().apply(new ApplySnapshot(snapshot));
-        } catch (Exception e) {
+        } catch (RuntimeException | ClassNotFoundException | IOException e) {
             log.error("{}: Error deserializing snapshot restore", context.getId(), e);
         }
     }
index 24132ea99979ca5b3ad45bdc0951c0195c30890b..2677baff6da40d1e2caba4a7b257594e5233bb3b 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.controller.cluster.raft;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.io.Serializable;
 import java.util.List;
 import org.opendaylight.controller.cluster.raft.persisted.ServerConfigurationPayload;
@@ -62,6 +63,9 @@ public class Snapshot implements Serializable {
                 electionTerm, electionVotedFor, serverConfig);
     }
 
+    @SuppressFBWarnings(value = "EI_EXPOSE_REP", justification = "Exposes a mutable object stored in a field but "
+            + "this is OK since this class is merely a DTO and does not process the byte[] internally. "
+            + "Also it would be inefficient to create a return copy as the byte[] could be large.")
     public byte[] getState() {
         return state;
     }
index 82f3e0dce02102034c54d127cdf83374313c61bc..1e573014a9ed6596ae6af84df0f724a9e730c34c 100644 (file)
@@ -7,14 +7,21 @@
  */
 package org.opendaylight.controller.cluster.raft.base.messages;
 
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 
 public class CaptureSnapshotReply {
     private final byte [] snapshot;
 
+    @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "Stores a reference to an externally mutable byte[] "
+            + "object but this is OK since this class is merely a DTO and does not process byte[] internally. "
+            + "Also it would be inefficient to create a copy as the byte[] could be large.")
     public CaptureSnapshotReply(byte [] snapshot) {
         this.snapshot = snapshot;
     }
 
+    @SuppressFBWarnings(value = "EI_EXPOSE_REP", justification = "Exposes a mutable object stored in a field but "
+            + "this is OK since this class is merely a DTO and does not process the byte[] internally. "
+            + "Also it would be inefficient to create a return copy as the byte[] could be large.")
     public byte [] getSnapshot() {
         return snapshot;
     }
index f3521deb3b2b8ef89bf70ef3e4ea2e63a77ac8a0..2918c5e75250e08223777819a6f82422b0af460a 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.controller.cluster.raft.client.messages;
 
 import com.google.common.base.Preconditions;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import javax.annotation.Nonnull;
 
 /**
@@ -29,6 +30,9 @@ public class GetSnapshotReply {
         return id;
     }
 
+    @SuppressFBWarnings(value = "EI_EXPOSE_REP", justification = "Exposes a mutable object stored in a field but "
+            + "this is OK since this class is merely a DTO and does not process the byte[] internally. "
+            + "Also it would be inefficient to create a return copy as the byte[] could be large.")
     @Nonnull
     public byte[] getSnapshot() {
         return snapshot;
index 487ea9b09db22ebce3d4d16d2dbc185dd61b0063..7ebc857444b1d2fae58cd2ce1b36337646b4068a 100644 (file)
@@ -35,7 +35,7 @@ public class AppendEntries extends AbstractRaftRPC {
     private final long prevLogTerm;
 
     // log entries to store (empty for heart beat - may send more than one for efficiency)
-    private transient List<ReplicatedLogEntry> entries;
+    private final List<ReplicatedLogEntry> entries;
 
     // leader's commitIndex
     private final long leaderCommit;
index 4528dcbf5e9370dec5631fd7efcd97745aaa876b..b64e902f3ff9f93e782c4114e6e690bbef971b0a 100644 (file)
@@ -9,6 +9,7 @@
 package org.opendaylight.controller.cluster.raft.messages;
 
 import com.google.common.base.Optional;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.io.Externalizable;
 import java.io.IOException;
 import java.io.ObjectInput;
@@ -30,6 +31,9 @@ public class InstallSnapshot extends AbstractRaftRPC {
     private final Optional<Integer> lastChunkHashCode;
     private final Optional<ServerConfigurationPayload> serverConfig;
 
+    @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "Stores a reference to an externally mutable byte[] "
+            + "object but this is OK since this class is merely a DTO and does not process byte[] internally. "
+            + "Also it would be inefficient to create a copy as the byte[] could be large.")
     public InstallSnapshot(long term, String leaderId, long lastIncludedIndex, long lastIncludedTerm, byte[] data,
             int chunkIndex, int totalChunks, Optional<Integer> lastChunkHashCode,
             Optional<ServerConfigurationPayload> serverConfig) {
@@ -62,6 +66,9 @@ public class InstallSnapshot extends AbstractRaftRPC {
         return lastIncludedTerm;
     }
 
+    @SuppressFBWarnings(value = "EI_EXPOSE_REP", justification = "Exposes a mutable object stored in a field but "
+            + "this is OK since this class is merely a DTO and does not process the byte[] internally. "
+            + "Also it would be inefficient to create a return copy as the byte[] could be large.")
     public byte[] getData() {
         return data;
     }
index 0f206b5d39d5b70f314801919f05292c683fa245..7138b634f4b49307e034d041709b082e154b1997 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.controller.cluster.raft.persisted;
 
 import com.google.common.collect.ImmutableList;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.io.ByteArrayOutputStream;
 import java.io.Externalizable;
 import java.io.IOException;
@@ -72,21 +73,24 @@ public final class ServerConfigurationPayload extends Payload implements Persist
     private static final Logger LOG = LoggerFactory.getLogger(ServerConfigurationPayload.class);
     private static final long serialVersionUID = 1L;
 
+    @SuppressFBWarnings(value = "SE_BAD_FIELD", justification = "This field is not Serializable but this class "
+            + "implements writeReplace to delegate serialization to a Proxy class and thus instances of this class "
+            + "aren't serialized. FindBugs does not recognize this.")
     private final List<ServerInfo> serverConfig;
     private final boolean migrated;
     private int serializedSize = -1;
 
-    private ServerConfigurationPayload(final @Nonnull List<ServerInfo> serverConfig, boolean migrated) {
+    private ServerConfigurationPayload(@Nonnull final List<ServerInfo> serverConfig, boolean migrated) {
         this.serverConfig = ImmutableList.copyOf(serverConfig);
         this.migrated = migrated;
     }
 
-    public ServerConfigurationPayload(final @Nonnull List<ServerInfo> serverConfig) {
+    public ServerConfigurationPayload(@Nonnull final List<ServerInfo> serverConfig) {
         this(serverConfig, false);
     }
 
     @Deprecated
-    public static ServerConfigurationPayload createMigrated(final @Nonnull List<ServerInfo> serverConfig) {
+    public static ServerConfigurationPayload createMigrated(@Nonnull final List<ServerInfo> serverConfig) {
         return new ServerConfigurationPayload(serverConfig, true);
     }
 
@@ -96,7 +100,8 @@ public final class ServerConfigurationPayload extends Payload implements Persist
         return migrated;
     }
 
-    public @Nonnull List<ServerInfo> getServerConfig() {
+    @Nonnull
+    public List<ServerInfo> getServerConfig() {
         return serverConfig;
     }
 
index 99c7b58724414c97f3c9a2e8e981e8b27dde83a6..7591bb51d8da832a291d95ddc06146e9469507fc 100644 (file)
@@ -65,7 +65,7 @@ public class SnapshotTrackerTest {
             tracker2.addChunk(3, chunk3, Optional.<Integer>absent());
             Assert.fail();
         } catch (SnapshotTracker.InvalidChunkException e) {
-            e.getMessage().startsWith("Invalid chunk");
+            // expected
         }
 
         // The first chunk's index must at least be FIRST_CHUNK_INDEX
index e947aede3b7bec14bec92abeb6ae77e33c68c2d8..68d6b619cd43bc6aa2d1ce582e32b2eb0bb03d4e 100644 (file)
@@ -38,12 +38,9 @@ public class MessageCollectorActor extends UntypedActor {
     private final List<Object> messages = new ArrayList<>();
 
     @Override public void onReceive(Object message) throws Exception {
-        if (message.equals(ARE_YOU_READY)) {
+        if (ARE_YOU_READY.equals(message)) {
             getSender().tell("yes", getSelf());
-            return;
-        }
-
-        if (GET_ALL_MESSAGES.equals(message)) {
+        } else if (GET_ALL_MESSAGES.equals(message)) {
             getSender().tell(new ArrayList<>(messages), getSelf());
         } else if (CLEAR_MESSAGES.equals(message)) {
             clear();