Fix race to become master in P4Runtime before pipeline config set

Change-Id: Id02e33a1d72d16ec49634ac57b6a4b56acdcf796
(cherry picked from commit 86f82c9e7ccd3912f77840e38eb7402a04f93681)
diff --git a/protocols/p4runtime/ctl/src/main/java/org/onosproject/p4runtime/ctl/P4RuntimeClientImpl.java b/protocols/p4runtime/ctl/src/main/java/org/onosproject/p4runtime/ctl/P4RuntimeClientImpl.java
index a5c3c13..5483edc 100644
--- a/protocols/p4runtime/ctl/src/main/java/org/onosproject/p4runtime/ctl/P4RuntimeClientImpl.java
+++ b/protocols/p4runtime/ctl/src/main/java/org/onosproject/p4runtime/ctl/P4RuntimeClientImpl.java
@@ -207,7 +207,7 @@
 
     @Override
     public CompletableFuture<Boolean> start() {
-        return supplyInContext(this::doBecomeMaster,
+        return supplyInContext(() -> sendMasterArbitrationUpdate(false),
                                "start-initStreamChannel");
     }
 
@@ -219,7 +219,7 @@
 
     @Override
     public CompletableFuture<Boolean> becomeMaster() {
-        return supplyInContext(this::doBecomeMaster,
+        return supplyInContext(() -> sendMasterArbitrationUpdate(true),
                                "becomeMaster");
     }
 
@@ -326,19 +326,20 @@
 
     /* Blocking method implementations below */
 
-    private boolean doBecomeMaster() {
-        final Uint128 newId = bigIntegerToUint128(
-                controller.newMasterElectionId(deviceId));
-        if (sendMasterArbitrationUpdate(newId)) {
-            clientElectionId = newId;
-            return true;
+    private boolean sendMasterArbitrationUpdate(boolean asMaster) {
+        BigInteger newId = controller.newMasterElectionId(deviceId);
+        if (asMaster) {
+            // Becoming master is a race. Here we increase our chances of win
+            // against other ONOS nodes in the cluster that are calling start()
+            // (which is used to start the stream RPC session, not to become
+            // master).
+            newId = newId.add(BigInteger.valueOf(1000));
         }
-        return false;
-    }
+        final Uint128 idMsg = bigIntegerToUint128(
+                controller.newMasterElectionId(deviceId));
 
-    private boolean sendMasterArbitrationUpdate(Uint128 electionId) {
         log.info("Sending arbitration update to {}... electionId={}",
-                 deviceId, uint128ToBigInteger(electionId));
+                 deviceId, newId);
         try {
             streamRequestObserver.onNext(
                     StreamMessageRequest.newBuilder()
@@ -346,9 +347,10 @@
                                     MasterArbitrationUpdate
                                             .newBuilder()
                                             .setDeviceId(p4DeviceId)
-                                            .setElectionId(electionId)
+                                            .setElectionId(idMsg)
                                             .build())
                             .build());
+            clientElectionId = idMsg;
             return true;
         } catch (StatusRuntimeException e) {
             log.error("Unable to perform arbitration update on {}: {}", deviceId, e.getMessage());