Finalize Match/Action Objects - ONOS-1728

* Added equals() and hashCode() methods to objects with IDs
* Added/Updates Javadocs
* Implemented rudimentary execute and query methods for
  Operations in the MatchActionModule.  Operations are preserved
  but not actually executed currently.
* Implemented factories for MatchActionOperationsId and
  MatchActionOperations
* Added unit tests to check creation and execution of MatchAction
* Added unit tests for new Immutable classes

Change-Id: Id865d04fd1048d00e533736c95c3052148041d95
diff --git a/src/test/java/net/onrc/onos/core/matchaction/MatchActionModuleTest.java b/src/test/java/net/onrc/onos/core/matchaction/MatchActionModuleTest.java
new file mode 100644
index 0000000..0a4e8d3
--- /dev/null
+++ b/src/test/java/net/onrc/onos/core/matchaction/MatchActionModuleTest.java
@@ -0,0 +1,137 @@
+package net.onrc.onos.core.matchaction;
+
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Set;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsInAnyOrder;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+
+/**
+ * Unit tests for the MatchActionModule.
+ */
+public class MatchActionModuleTest {
+
+    /**
+     * Tests that MatchAction objects added by the executeOperations()
+     * method are properly returned by the getMatchActions() method.
+     */
+    @Test
+    public void testMatchActionModuleGlobalEntriesSet() {
+
+        final int iterations = 5;
+        final MatchActionModule module = new MatchActionModule();
+        final ArrayList<MatchAction> generatedMatchActions = new ArrayList<>();
+
+        // Add some test MatchAction objects. 25 will be added, in 5 blocks
+        // of 5.
+        for (int operationsIteration = 1;
+             operationsIteration <= iterations;
+             operationsIteration++) {
+            final MatchActionOperationsId id =
+                    MatchActionOperationsId.createNewOperationsId();
+            assertThat(id, is(notNullValue()));
+            final MatchActionOperations operations =
+                    MatchActionOperations.createMatchActionsOperations(id);
+            assertThat(operations, is(notNullValue()));
+
+            for (int entriesIteration = 1;
+                 entriesIteration <= iterations;
+                 entriesIteration++) {
+
+                final String entryId = "MA" +
+                        Integer.toString(operationsIteration) +
+                        Integer.toString(entriesIteration);
+                final MatchAction matchAction =
+                        new MatchAction(entryId, null, null, null);
+                final MatchActionOperationEntry entry =
+                        new MatchActionOperationEntry(MatchActionOperations.Operator.ADD,
+                                                      matchAction);
+                operations.addOperation(entry);
+                generatedMatchActions.add(matchAction);
+            }
+
+            // Add the MatchActions generated by this iteration
+            final boolean result = module.executeOperations(operations);
+            assertThat(result, is(true));
+        }
+
+        // Get the list of generated MatchAction objects and make sure its
+        // length is correct.
+        final int generatedCount = generatedMatchActions.size();
+        final Set<MatchAction> matchActions = module.getMatchActions();
+        assertThat(matchActions, hasSize(generatedCount));
+
+        // Make sure that all the created items are in the list
+        final MatchAction[] generatedArray =
+                generatedMatchActions.toArray(new MatchAction[generatedCount]);
+        assertThat(matchActions, containsInAnyOrder(generatedArray));
+
+        //  Make sure that the returned list cannot be modified
+        Throwable errorThrown = null;
+        try {
+            matchActions.add(new MatchAction("", null, null, null));
+        } catch (UnsupportedOperationException e) {
+            errorThrown = e;
+        }
+        assertThat(errorThrown, is(notNullValue()));
+    }
+
+    /**
+     * Tests that adding a duplicate MatchAction via executeOperations()
+     * returns an error.
+     */
+    @Test
+    public void testAddingDuplicateMatchAction() {
+
+        // Create two MatchAction objects using the same ID
+        final MatchAction matchAction =
+                new MatchAction("ID", null, null, null);
+        final MatchAction duplicateMatchAction =
+                new MatchAction("ID", null, null, null);
+
+        // create Operation Entries for the two MatchAction objects
+        final MatchActionOperationEntry entry =
+                new MatchActionOperationEntry(MatchActionOperations.Operator.ADD,
+                        matchAction);
+        final MatchActionOperationEntry duplicateEntry =
+                new MatchActionOperationEntry(MatchActionOperations.Operator.ADD,
+                        duplicateMatchAction);
+
+        // Create an Operations object to execute the first MatchAction
+        final MatchActionOperationsId id =
+                MatchActionOperationsId.createNewOperationsId();
+        assertThat(id, is(notNullValue()));
+        final MatchActionOperations operations =
+                MatchActionOperations.createMatchActionsOperations(id);
+        operations.addOperation(entry);
+
+        // Create a module to use to execute the Operations.
+        final MatchActionModule module = new MatchActionModule();
+
+        // Execute the first set of Operations.  This
+        // should succeed.
+        final boolean result = module.executeOperations(operations);
+        assertThat(result, is(true));
+
+        // Now add the duplicate entry.  This should fail.
+        final MatchActionOperationsId idForDuplicate =
+                MatchActionOperationsId.createNewOperationsId();
+        assertThat(idForDuplicate, is(notNullValue()));
+        final MatchActionOperations operationsForDuplicate =
+                MatchActionOperations.createMatchActionsOperations(idForDuplicate);
+        operationsForDuplicate.addOperation(duplicateEntry);
+
+        final boolean resultForDuplicate =
+                module.executeOperations(operationsForDuplicate);
+        assertThat(resultForDuplicate, is(false));
+
+        // Now add the original entry again.  This should fail.
+        final boolean resultForAddAgain = module.executeOperations(operations);
+        assertThat(resultForAddAgain, is(false));
+    }
+}