Adding to current partition, and releaseLock bug 38/83638/3
authorTschaen, Brendan <ctschaen@att.com>
Thu, 28 Mar 2019 17:46:50 +0000 (13:46 -0400)
committerTschaen, Brendan <ctschaen@att.com>
Thu, 28 Mar 2019 19:52:23 +0000 (15:52 -0400)
Change-Id: I9801656a32480c26b39dea5ae59fd27053d92f29
Issue-ID: MUSIC-374
Signed-off-by: Tschaen, Brendan <ctschaen@att.com>
mdbc-server/src/main/java/org/onap/music/mdbc/examples/MdbcTestClient.java
mdbc-server/src/main/java/org/onap/music/mdbc/mixins/LockResult.java
mdbc-server/src/main/java/org/onap/music/mdbc/mixins/MusicMixin.java
mdbc-server/src/main/java/org/onap/music/mdbc/ownership/OwnershipAndCheckpoint.java

index 60c97d1..fddd305 100644 (file)
@@ -106,7 +106,7 @@ public class MdbcTestClient {
 \r
         final String insertSQL = "INSERT INTO Persons VALUES (1, 'Martinez', 'Juan', 'KACB', 'ATLANTA');";\r
         final String insertSQL1 = "DELETE FROM Persons WHERE PersonID=2;";\r
-        final String insertSQL2 = "INSERT INTO Persons VALUES (2, 'Smith', 'JOHN', 'GNOC', 'BEDMINSTER');";\r
+        final String insertSQL2 = "INSERT INTO Persons2 VALUES (2, 'Smith', 'JOHN', 'GNOC', 'BEDMINSTER');";\r
         final String insertSQL3 = "UPDATE Persons SET FirstName='JOSH' WHERE LastName='Smith';";\r
         final String insertSQL4 = "UPDATE Persons SET FirstName='JOHN' WHERE LastName='Smith';";\r
 \r
@@ -121,7 +121,7 @@ public class MdbcTestClient {
 \r
         try {\r
             execute = insertStmt.execute(insertSQL);\r
-            execute = insertStmt.execute(insertSQL1);\r
+            //execute = insertStmt.execute(insertSQL1);\r
             execute = insertStmt.execute(insertSQL2);\r
             //execute = insertStmt.execute(insertSQL3);\r
             //execute = insertStmt.execute(insertSQL4);\r
index 8055cae..a05e583 100644 (file)
@@ -27,44 +27,45 @@ import org.onap.music.mdbc.Range;
 public class LockResult{
     private boolean successful;
     private UUID musicRangeInformationIndex;
-    private String ownerId;
+    private String lockId;
     private List<Range> ranges;
     private boolean newLock;
-    private long backOffPeriodS;
+    /** back off time in milliseconds */
+    private long backOffPeriodms;
 
-    public LockResult(boolean succesful, UUID rowId, String ownerId, boolean newLock, List<Range> ranges){
+    public LockResult(boolean succesful, UUID rowId, String lockId, boolean newLock, List<Range> ranges){
         this.successful = true;
         this.musicRangeInformationIndex = rowId;
-        this.ownerId=ownerId;
+        this.lockId=lockId;
         this.newLock=newLock;
         this.ranges=ranges;
     }
     /**
      * Please use constructor which specifies whether lock result was succesful
      * @param rowId
-     * @param ownerId
+     * @param lockId
      * @param newLock
      * @param ranges
      */
     @Deprecated
-    public LockResult(UUID rowId, String ownerId, boolean newLock, List<Range> ranges){
+    public LockResult(UUID rowId, String lockId, boolean newLock, List<Range> ranges){
         this.successful = true;
         this.musicRangeInformationIndex = rowId;
-        this.ownerId=ownerId;
+        this.lockId=lockId;
         this.newLock=newLock;
         this.ranges=ranges;
     }
     public LockResult(boolean successful, long backOffTimems) {
         this.successful = successful;
-        this.backOffPeriodS = backOffTimems;
+        this.backOffPeriodms = backOffTimems;
     }
     
     public boolean wasSuccessful() {
         return successful;
     }
     
-    public String getOwnerId(){
-        return ownerId;
+    public String getLockId(){
+        return lockId;
     }
     public boolean isNewLock(){
         return newLock;
@@ -86,7 +87,7 @@ public class LockResult{
      * @return
      */
     public long getBackOffPeriod() {
-        return this.backOffPeriodS;
+        return this.backOffPeriodms;
     }
     
 }
\ No newline at end of file
index e548f1a..c176ad9 100644 (file)
@@ -106,13 +106,14 @@ public class MusicMixin implements MusicInterface {
     /** The default property value to use for the Cassandra IP address. */
     public static final String DEFAULT_MUSIC_ADDRESS  = "localhost";
     /** The default property value to use for the Cassandra replication factor. */
-    public static final int    DEFAULT_MUSIC_RFACTOR  = 3;
+    public static final int    DEFAULT_MUSIC_RFACTOR  = 1;
     /** The default primary string column, if none is provided. */
     public static final String MDBC_PRIMARYKEY_NAME = "mdbc_cuid";
     /** Type of the primary key, if none is defined by the user */
     public static final String MDBC_PRIMARYKEY_TYPE = "uuid";
     public static final boolean DEFAULT_COMPRESSION = true;
 
+    public static final boolean ENABLE_NETWORK_TOPOLOGY_STRATEGY = false;
 
     //\TODO Add logic to change the names when required and create the tables when necessary
     private String musicTxDigestTableName = "musictxdigest";
@@ -253,12 +254,11 @@ public class MusicMixin implements MusicInterface {
     public static void createKeyspace(String keyspace, int replicationFactor) throws MDBCServiceException {
         Map<String,Object> replicationInfo = new HashMap<>();
         replicationInfo.put("'class'", "'NetworkTopologyStrategy'");
-        if(replicationFactor==3){
+        if (ENABLE_NETWORK_TOPOLOGY_STRATEGY && replicationFactor==3) {
             replicationInfo.put("'dc1'", 1);
             replicationInfo.put("'dc2'", 1);
             replicationInfo.put("'dc3'", 1);
-        }
-        else {
+        } else {
             replicationInfo.put("'class'", "'SimpleStrategy'");
             replicationInfo.put("'replication_factor'", replicationFactor);
         }
@@ -1262,7 +1262,7 @@ public class MusicMixin implements MusicInterface {
             musicTxDigestTableName, isLatest);
         ReturnType returnType = MusicCore.criticalPut(music_ns, musicRangeInformationTableName, row.getPartitionIndex().toString(),
             appendQuery, 
-            lock.getOwnerId()
+            lock.getLockId()
             , null);
         if(returnType.getResult().compareTo(ResultType.SUCCESS) != 0 ){
             logger.error(EELFLoggerDelegate.errorLogger, "Error when executing change isLatest operation with return type: "+returnType.getMessage());
@@ -1996,15 +1996,19 @@ public class MusicMixin implements MusicInterface {
         return result;
     }
 
-    private void unlockKeyInMusic(String table, String key, String lockref) {
-        String fullyQualifiedKey= music_ns+"."+ table+"."+lockref;
-        MusicCore.destroyLockRef(fullyQualifiedKey,lockref);
+    private void unlockKeyInMusic(String table, String key, String lockref) throws MDBCServiceException {
+        String fullyQualifiedKey= music_ns+"."+ table+"."+key;
+        try {
+            MusicCore.voluntaryReleaseLock(fullyQualifiedKey,lockref);
+        } catch (MusicLockingException e) {
+            throw new MDBCServiceException(e.getMessage(), e);
+        }
     }
 
     @Override
     public void releaseLocks(Map<UUID,LockResult> newLocks) throws MDBCServiceException{
         for(Map.Entry<UUID,LockResult> lock : newLocks.entrySet()) {
-            unlockKeyInMusic(musicRangeInformationTableName, lock.getKey().toString(), lock.getValue().getOwnerId());
+            unlockKeyInMusic(musicRangeInformationTableName, lock.getKey().toString(), lock.getValue().getLockId());
         }
     }
 
@@ -2015,7 +2019,7 @@ public class MusicMixin implements MusicInterface {
             if(lock == null)
                 continue;
             unlockKeyInMusic(musicRangeInformationTableName, r.getPartitionIndex().toString(),
-                lock.getOwnerId());
+                lock.getLockId());
             newLocks.remove(r.getPartitionIndex());
         }
     }
@@ -2025,7 +2029,7 @@ public class MusicMixin implements MusicInterface {
         for(Map.Entry<UUID,LockResult> lock : newLocks.entrySet()) {
             UUID id = lock.getKey();
             if(id!=finalRow){
-                unlockKeyInMusic(musicRangeInformationTableName, id.toString(), lock.getValue().getOwnerId());
+                unlockKeyInMusic(musicRangeInformationTableName, id.toString(), lock.getValue().getLockId());
                 toErase.add(id);
             }
         }
@@ -2083,6 +2087,7 @@ public class MusicMixin implements MusicInterface {
         latestDag.addNewNode(r,new ArrayList<>(rangesAndDependents.getValue()));
     }
 
+
     private List<MusicRangeInformationRow> setReadOnlyAnyDoubleRow(Dag latestDag,List<MusicRangeInformationRow> rows, Map<UUID,LockResult> locks)
         throws MDBCServiceException{
         List<MusicRangeInformationRow> returnInfo = new ArrayList<>();
@@ -2126,7 +2131,7 @@ public class MusicMixin implements MusicInterface {
         releaseLocks(changed,locks);
         releaseAllLocksExcept(row.getPartitionIndex(),locks);
         LockResult ownRow = locks.get(row.getPartitionIndex());
-        return new OwnershipReturn(ownershipId, ownRow.getOwnerId(), ownRow.getIndex(),ranges,extendedDag);
+        return new OwnershipReturn(ownershipId, ownRow.getLockId(), ownRow.getIndex(),ranges,extendedDag);
     }
 
     /**
@@ -2151,12 +2156,7 @@ public class MusicMixin implements MusicInterface {
         if(ownerId==null||ownerId.isEmpty()||rangeId==null||rangeId.isEmpty()){
             return;
         }
-        String fullyQualifiedMriKey = music_ns+"."+ musicRangeInformationTableName+"."+rangeId;
-        try {
-            MusicCore.voluntaryReleaseLock(fullyQualifiedMriKey,ownerId);
-        } catch (MusicLockingException e) {
-            throw new MDBCServiceException(e.getMessage(), e);
-        }
+        unlockKeyInMusic(musicRangeInformationTableName, rangeId, ownerId);
     }
 
     /**
index e76e1b1..b8b26e0 100644 (file)
@@ -271,43 +271,47 @@ public class OwnershipAndCheckpoint{
     /**
      * Use this functions to verify ownership, and taking locking ownership of new ranges
      * @param ranges the ranges that should be own after calling this function
-     * @param partition current information of the ownership in the system
+     * @param currPartition current information of the ownership in the system
      * @param ownOpId is the id used to describe this ownership operation (it is not used to create the new row, if any is
      *                required
      * @return an object indicating the status of the own function result
      * @throws MDBCServiceException
      */
-    public OwnershipReturn own(MusicInterface mi, List<Range> ranges, DatabasePartition partition, UUID opId) throws MDBCServiceException {
+    public OwnershipReturn own(MusicInterface mi, List<Range> ranges,
+            DatabasePartition currPartition, UUID opId) throws MDBCServiceException {
         
-        if(ranges == null || ranges.isEmpty()) {
+        if (ranges == null || ranges.isEmpty()) {
               return null;
         }
 
-        Map<UUID,LockResult> newLocks = new HashMap<>();
         //Init timeout clock
         startOwnershipTimeoutClock(opId);
-        if(partition.isLocked()&&partition.getSnapshot().containsAll(ranges)) {
-            return new OwnershipReturn(opId,partition.getLockId(),partition.getMRIIndex(),partition.getSnapshot(),null);
+        if (currPartition.isLocked()&&currPartition.getSnapshot().containsAll(ranges)) {
+            return new OwnershipReturn(opId,currPartition.getLockId(),currPartition.getMRIIndex(),
+                    currPartition.getSnapshot(),null);
         }
         //Find
+        Map<UUID,LockResult> newLocks = new HashMap<>();
         List<Range> rangesToOwn = mi.getRangeDependencies(ranges);
         List<MusicRangeInformationRow> rows = extractRowsForRange(mi,rangesToOwn, false);
         Dag toOwn =  Dag.getDag(rows,rangesToOwn);
         Dag currentlyOwn = new Dag();
-        while( (toOwn.isDifferent(currentlyOwn) || !currentlyOwn.isOwned() ) &&
+        while ( (toOwn.isDifferent(currentlyOwn) || !currentlyOwn.isOwned() ) &&
                 !timeout(opId)
-            ){
-            takeOwnershipOfDag(mi, partition, opId, newLocks, toOwn);
+            ) {
+            takeOwnershipOfDag(mi, currPartition, opId, newLocks, toOwn);
             currentlyOwn=toOwn;
             //TODO instead of comparing dags, compare rows
             rows = extractRowsForRange(mi, rangesToOwn, false);
             toOwn =  Dag.getDag(rows,rangesToOwn);
         }
-        if(!currentlyOwn.isOwned() || toOwn.isDifferent(currentlyOwn)){
-           mi.releaseLocks(newLocks);
-           stopOwnershipTimeoutClock(opId);
-           logger.error("Error when owning a range: Timeout");
-           throw new MDBCServiceException("Ownership timeout");
+        if (!currentlyOwn.isOwned() || toOwn.isDifferent(currentlyOwn)) {
+            //hold on to previous partition
+            newLocks.remove(currPartition.getMRIIndex());
+            mi.releaseLocks(newLocks);
+            stopOwnershipTimeoutClock(opId);
+            logger.error("Error when owning a range: Timeout");
+            throw new MDBCServiceException("Ownership timeout");
         }
         Set<Range> allRanges = currentlyOwn.getAllRanges();
         List<MusicRangeInformationRow> isLatestRows = extractRowsForRange(mi, new ArrayList<>(allRanges), true);
@@ -317,24 +321,27 @@ public class OwnershipAndCheckpoint{
     
     /**
      * Step through dag and take lock ownership of each range
-     * @param partition
+     * @param partition current partition owned by system
      * @param opId
      * @param newLocks
      * @param toOwn
      * @throws MDBCServiceException
      */
-    private void takeOwnershipOfDag(MusicInterface mi, DatabasePartition partition, UUID opId, Map<UUID, LockResult> newLocks, Dag toOwn)
-            throws MDBCServiceException {
+    private void takeOwnershipOfDag(MusicInterface mi, DatabasePartition partition, UUID opId,
+            Map<UUID, LockResult> newLocks, Dag toOwn) throws MDBCServiceException {
+        
         while(toOwn.hasNextToOwn()){
             DagNode node = toOwn.nextToOwn();
             MusicRangeInformationRow row = node.getRow();
             UUID uuid = row.getPartitionIndex();
-            if(partition.isLocked()&&partition.getMRIIndex().equals(uuid)||
-                newLocks.containsKey(uuid) ||
-                !row.getIsLatest()){
+            if (partition.isLocked() && partition.getMRIIndex().equals(uuid) ||
+                !row.getIsLatest()) {
                 toOwn.setOwn(node);
-            }
-            else{
+                newLocks.put(uuid, new LockResult(true, uuid, partition.getLockId(),
+                        false, partition.getSnapshot()));
+            } else if (newLocks.containsKey(uuid)) {
+                toOwn.setOwn(node);
+            } else {
                 LockRequest request = new LockRequest(MusicMixin.musicRangeInformationTableName,uuid,
                         new ArrayList(node.getRangeSet()));
                 LockResult result = null;