Deprecate ask-based protocol messages Since we have removed the ask-based client, we really have no way of testing ask-based messages' interaction with Shard. We keep Shard compatible, but deprecate all ask-based messages and methods/classes dealing with them on the backend. JIRA: CONTROLLER-2054 Change-Id: I5764713b686ae11f8d750e691576b6d20637ab7d Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
Fixup Sonar issues Perform automatic conversions and also fixup Sonar issues reported, which tend to be very minor. Change-Id: Ia0d980105f4635218bacb9161a39ecb87838a9ff Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
Migrate nullness annotations This mass-migrates sal-distributed-datastore to use JDT nullness annotations instead of JSR305. Change-Id: I2cd739e3db8c074a55e335e17297a23065775d6a Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
Fix shard deadlock in 3 nodes JIRA: CONTROLLER-1836 Change-Id: I10a9cb43bcdb35f66abebb054f37c05e7fda54e7 Signed-off-by: Tom Pantelis <tompantelis@gmail.com>
Fix FindBugs warnings in sal-distributed-datastore and enable enforcement Several warnings were suppressed via annotation with justification provided. Other warnings that were fixed: - remove redundant implements in several classes - "The referenced methods have names that differ only by capitalization" warnings. This is checked across all classes for consistency. The main offender was getTransactionID vs. getTransactionId. I changed all methods to getTransactionId and associated fields to transactionId. - unsynchronized access to a field where access is synchronized elsewhere (in DataTreeChangeListenerProxy and DatastoreContextIntrospector). - catching Exception instead of catching more specific exception types that are thrown from the try block. - unconfirmed casts - verify via Preconditions check to avoid warning - unnecessarily calling toString() on a String instance - synchronizing an AtomicInteger instance (in ThreePhaseCommitCohortProxy) - not an issue in this case but changed to synchronize a separate Object in lieu of supressing the warning. - unsynchronized to SimpleDateFormat which isn't thread-safe (in ShardStats). - potential null-pointer access of 'shard' in ShardStats - changed to pass 'shard' to the ctor in lieu of setter. - calling String#getBytes w/o specifying encoding (in DataTreeModificationOutput). - privileged access to create ClassLoader in ActorSystemProviderImpl although not likely a SecurityManager would ever be present. Change-Id: I0a87208f3f200fbe4f78e950c21419fbab154d94 Signed-off-by: Tom Pantelis <tpanteli@brocade.com>
BUG-5280: switch transaction IDs from String to TransactionIdentifier This patch switches primary frontend messages to use TransactionIdentifier instead of plain Strings. Change-Id: Ib04a2e4882dfcc43eea5369bf162889fd7ef5472 Signed-off-by: Robert Varga <rovarga@cisco.com>
Remove returnSerialized from ForwardedReadyTransaction With the removal of the pre-Lithium transaction messages, the returnSerialized field in ForwardedReadyTransaction is no longer used and thus was removed. Change-Id: I4a23ed77ee1960d3bb634511a2222dfcd213062f Signed-off-by: Tom Pantelis <tpanteli@brocade.com>
Transaction message retry when no shard leader present Implemented retry of transaction ready messages, ForwardedReadyTransaction, ReadyLocalTransaction, and BatchedModifications, when there's no current shard leader. A new class, ShardTransactionMessageRetrySupport, maintains a list of messages to retry and handles the retry logic. If there is no leader, the message is added to the list and a timer (2 * election time out) is started. If a leader is elected, on leader changed, the messages are retried. If no leader is elected in time, the messages are removed and NoShardLeaderException is returned. Change-Id: Iade3fd245982d75ee97acf0534e9224551d9e45d Signed-off-by: Tom Pantelis <tpanteli@brocade.com>
Guard against null transaction IDs This pushes down the null guards so that we can track down the source of nulls. Change-Id: Id94db7ba1810b2331f625f335ee610b3a22b3c44 Signed-off-by: Robert Varga <rovarga@cisco.com>
Move Tx ready call from ShardWriteTransaction to Shard On ready, the ShardWriteTransaction actor calls ready on the ReadWriteShardDataTreeTransaction to obtain the ShardDataTreeCohort and passes it with the ForwardedReadyTransaction message sent to the Shard. Internally the ReadWriteShardDataTreeTransaction accesses its parent, which is either the ShardDataTree or a ShardDataTreeTransactionChain, to obtain the ShardDataTreeCohort. The parent holds unsynchronized internal Shard state and is potentially unsafe to indirectly leak to the transaction actor. This isn't an issue with the ShardDataTree b/c finishTransaction doesn't access internal state but ShardDataTreeTransactionChain does. To be safe, we need to move the ready call to the Shard. Therefore, the ReadWriteShardDataTreeTransaction instance is now passed with the ForwardedReadyTransaction and the ShardCommitCoordinator now calls ready. Change-Id: I59295936944326b68506380519f8ade3b11164d9 Signed-off-by: Tom Pantelis <tpanteli@brocade.com>
Removed unused Modification field in ForwardedReadyTransaction The Modification field is no longer used. Change-Id: I1b0ace3cf7a663fa3c14da1b5785fc05b77203bc Signed-off-by: Tom Pantelis <tpanteli@brocade.com>
CDS: switch persistence to persisting the candidates With us being in control of the DataTree, we can now use DataTreeCandidate for replication and persistence. Add the appropriate payload and add appropriate hooks. Exposing the DataTreeCandidate from the cohort is actually pushing towards having our own cohort type -- ShardDataTreeCohort. With that we can get rid of DOMStoreThreePhaseCommitCohort, so eliminate its mention to prevent accidental leakage. Change-Id: I37a22b445f955330193c762894764feee94bebdb Signed-off-by: Robert Varga <rovarga@cisco.com>
Elide front-end 3PC for single-shard Tx A new method, directCommit, was added to TransactionContext. In TransactionContextImpl#directCommit, it sends the final ready BatchedModifications message as before but with a new flag, doCommitOnReady, set to true. In ShardCommitCoordinator, if doCommitOnReady is true, it immediately initiates the canCommit phase without waiting for the CanCommitTransaction message. In ShardWriteTransaction, if doCommitOnReady is true, it sets a new similar flag in the ForwardedReadyTransaction message. Similarly, the ShardCommitCoordinator immediately initiates the canCommit phase. This code path is executed for read-write transactions as they still utilize the transaction actor. In TransactionProxy, when only 1 shard was accessed, it creates a SingleCommitCohortProxy instance. This class also implements DOMStoreThreePhaseCommitCohort but the 3 phases are essentially a no-op with direct commit. The canCommit phase simply waits for the direct commit Future to complete and returns success (true). If a failure occurs from the Shard, the exception is propagated to the caller. For backwards compatibility, we still need the ThreePhaseCommitCohortProxy even with a single-shard transaction. A complication with this is that TransactionProxy#ready may not know immediately if it can do direct commit or not because it may not have the TransactionContext instance yet due to the async nature of things. So in either case it still creates a SingleCommitCohortProxy. When it gets the callback to finally complete the operation, it checks the TransactionContext to see if it supports direct commit (only pre-Lithium versions won't). If supported, it calls directCommit, otherwise readyTransaction. In the SingleCommitCohortProxy, on successful completion of the ready/direct commit Future, it checks the response type. If it's an ActorSelection then it needs to do 3-phase commit so it creates and delegates to a ThreePhaseCommitCohortProxy. I moved the code in Shard#handleCommitTransaction to the ShardCommitCoordinator as this is also needed for direct commit. I also moved the handleForwardedReadyTransaction code into ShardCommitCoordinator to make it easier to handle direct commit. Change-Id: I40b04dd5abd24c78709598a5acfc16484e165427 Signed-off-by: Tom Pantelis <tpanteli@brocade.com>
Use BatchedModifications message in place of ReadyTransaction message For the optimized write transactions (currently disabled), we used the last BatchedModifications message with the ready flag set to elide sending the ReadyTransaction message. We can do this in general for both read-write and write-only. In ShardWriteTransaction, if the BatchedModifications indicates ready, it simply calls readyTransaction to send ForwardedReadyTransaction message to the shard, same as with the ReadyTransacton message. Instead of returning a BatchedModificationsReply with the cohort path, I kept the ReadyTransactionReply so the Shard code mostly remains the same - otherwise we'd have to introduce an equivalent batched ForwardedReadyTransaction message. I also made ReadyTransactionReply Externalizable so we don't have to deal with sending it serialized or not (except for backwards compatibility - had to keep the protobuff class). TransactionContextImpl#readyTransaction is now the same as WriteTransactionContextImpl#readyTransaction so WriteTransactionContextImpl is no longer needed and was removed. Change-Id: I5175c77ca08a1877af9593a28e7c4cb46f03287a Signed-off-by: Tom Pantelis <tpanteli@brocade.com>
Bug 2294: Handle Shard backwards compatibility Implemented as outlined in Bug 2294. Change-Id: I14aa8ef5f320f9d165492396ece4ea63cce9b0c3 Signed-off-by: tpantelis <tpanteli@brocade.com>
Bug-2136 : Clustering : When a transaction is local then do not serialize the Reading/Writing of data Ensured that the TransactionContext created for each shard within the transaction has a flag isShardLocal. if the flag is false, we would be using ProfoBuf to serialize. Change-Id: I3dc754ae58566212237a6ce385e5f5bb63afd4e0 Signed-off-by: Kamal Rameshan <kramesha@cisco.com>
Bug 2038: Ensure only one concurrent 3-phase commit in Shard Added a ShardCommitCoordinator class that ensures there's only one concurrent 3-phase commit. The following outlines the new commit workflow: - On ready, the ShardTransaction creates the dom store cohort and forwards a new ForwardedReadyTransaction message to the shard. - The shard calls its ShardCommitCoordinator to add the cohort and modificaton to a cached keyed by transaction ID. - On CanCommitTransaction message, the ShardCommitCoordinator looks up and removes the cohort entry from the cache corresponding to the transaction ID passed via the CanCommit message. The ShardCommitCoordinator also caches the cohort entry for the current transaction in progress. If there's no transaction in progress, the committing transaction becomes the current transaction and canCommit is called on the cohort. Otherwise, the cohort entry is queued to be processed after the current tranaction completes. - On CommitTransaction message, if the transaction ID passed via the Commit message matches the currently cached cohort entry, the preCommit and commit phases are performed. When complete, the ShardCommitCoordinator dequeues the next waiting transaction cohort entry, if any, and process it. If a Tx is aborted and it is the current transaction, the ShardCommitCoordinator handles it as a completed Tx. Implemented a timeout mechanism using the akka scheduler such that if the commit message isn't received after a period of time (default 30 s) after the canCommit message, the transaction is aborted so that the next transaction can proceed. This is to handle remote node or network failures during a 3-phrase commit. The ThreePhaseCommitCohort actor was removed along with the ForwardedCommitTransaction. Change-Id: Iaa5692ca45cd7635d1a06a609f4bf98bec50df14 Signed-off-by: tpantelis <tpanteli@brocade.com>