Пример #1
0
        /// <summary>
        /// Abort callback for a range partition service
        /// </summary>
        /// <param name="isInbound">Is Inbound/Outbound Session</param>
        /// <param name="sourceServiceInstanceName">Service instance name</param>
        /// <param name="partitionKey">Partition key range</param>
        /// <param name="session">Aborted session</param>
        public void SessionAbortedByPartner(
            bool isInbound, Uri sourceServiceInstanceName, IntegerPartitionKeyRange partitionKey, IReliableMessagingSession session)
        {
            string sessionKind = isInbound ? "Inbound" : "Outbound";
            string partnerKind = isInbound ? "Source" : "Target";

            LogHelper.Log("{0} Session Aborted for Int64 Partition {1} {2}:{3}-{4}", sessionKind, partnerKind, sourceServiceInstanceName, partitionKey.IntegerKeyLow, partitionKey.IntegerKeyHigh);
        }
Пример #2
0
 /// <summary>
 /// Creates a new PartitionKey specifing its service instance name, partition range and numbered kind.
 /// </summary>
 /// <param name="serviceInstanceName">Service name of the role</param>
 /// <param name="lowKey">Partition range - Low key</param>
 /// <param name="highKey">Partition range - High key</param>
 public PartitionKey(Uri serviceInstanceName, long lowKey, long highKey)
 {
     //Set service and partition info.
     this.ServiceInstanceName   = serviceInstanceName;
     this.serviceInstanceString = this.ServiceInstanceName.OriginalString;
     this.partitionRange        = new IntegerPartitionKeyRange {
         IntegerKeyLow = lowKey, IntegerKeyHigh = highKey
     };
     this.Kind = PartitionKind.Numbered;
 }
        /// <summary>
        /// Callback offering a session.
        /// Use the instance number (in URI segment - 3) to assign the callback session to the right global partition object.
        /// Three overloads for singleton, numbered and named partition types
        /// </summary>
        /// <param name="sourceServiceInstanceName"></param>
        /// <param name="partitionKey">Numbered partition types</param>
        /// <param name="session"></param>
        /// <returns> true to grant permission and false to deny</returns>
        public bool AcceptInboundSession(
            Uri sourceServiceInstanceName, IntegerPartitionKeyRange partitionKey, IReliableMessagingSession session)
        {
            string key = sourceServiceInstanceName + ":" + partitionKey.IntegerKeyLow + ":" + partitionKey.IntegerKeyHigh;

            if (!this.myPartitionRecord.InboundSessions.ContainsKey(key))
            {
                this.myPartitionRecord.InboundSessions.Add(key, session);
            }
            return(true);
        }
Пример #4
0
 /// <summary>
 /// Creates an instance of the partition instance
 /// </summary>
 /// <param name="name">Name of the partition instance</param>
 /// <param name="type">Type of the partition</param>
 /// <param name="stringPartitionKey">Name of the partition if Named partition type</param>
 /// <param name="intPartitionKey">Range of the partition if range partition type</param>
 public PartitionRecord(Uri name, PartitionKeyType type, string stringPartitionKey, IntegerPartitionKeyRange intPartitionKey)
 {
     this.InstanceName  = name;
     this.PartitionType = type;
     this.StringPartitionPartitionKey = stringPartitionKey;
     this.Int64PartitionPartitionKey  = intPartitionKey;
     this.InboundSessions             = new Dictionary <string, IReliableMessagingSession>();
 }
Пример #5
0
 public void SessionAbortedByPartner(bool isInbound, Uri sourceServiceInstanceName, IntegerPartitionKeyRange range, IReliableMessagingSession session)
 {
     this.SessionAbortedByPartner(isInbound, new PartitionKey(sourceServiceInstanceName, range.IntegerKeyLow, range.IntegerKeyHigh), session);
 }
Пример #6
0
        /// <summary>
        /// Manages the Inbound Session Callback for a numbered service type.
        /// </summary>
        /// <param name="sourceServiceInstanceName">The inbound source service name</param>
        /// <param name="keyRange">The key range of the inbound source service partition</param>
        /// <param name="session">The inbound reliable messaging session</param>
        /// <returns>true if accepted, false otherwise</returns>
        public bool AcceptInboundSession(Uri sourceServiceInstanceName, IntegerPartitionKeyRange keyRange, IReliableMessagingSession session)
        {
            var key = new PartitionKey(sourceServiceInstanceName, keyRange.IntegerKeyLow, keyRange.IntegerKeyHigh);

            return(this.AcceptInboundSession(key, session));
        }
Пример #7
0
        /// <summary>
        /// Create and Initialize partitions for the given service instance .
        /// </summary>
        /// <param name="instance">Initialize partitions for this service instance</param>
        /// <param name="isRandomPartitionType">true - if the partition type is selected randomly - String or Int64</param>
        /// <param name="type">Set the partition type to this parameter, if isRandomPartitionType is false.
        /// Singleton type is not allowed as we will set this type if instance partitions count = 1</param>
        /// <param name="int64PartitionKeyLowValMultiplier"></param>
        static void InitializePartitions(InstanceRecord instance, bool isRandomPartitionType, PartitionKeyType type, int int64PartitionKeyLowValMultiplier)
        {
            // Singletone is not a valid type
            VS.Assert.IsTrue(type != PartitionKeyType.Singleton, "unexpected partition key type {0} in StartSessionManagersForServiceInstance", type);

            // Ensure we have a valid partitions count > 0
            Uri instanceName   = instance.InstanceName;
            int partitionCount = instance.CountOfPartitions;

            VS.Assert.IsTrue(partitionCount > 0, "unexpected partitionCount {0} in StartSessionManagersForServiceInstance", partitionCount);

            // singleton case
            if (partitionCount == 1)
            {
                PartitionRecord newPartition = new PartitionRecord(
                    instanceName,
                    PartitionKeyType.Singleton,
                    null,
                    new IntegerPartitionKeyRange());
                instance.Partitions[0] = newPartition;
                return;
            }

            bool stringPartitions = false;

            // randomly allocate string or int64 partition type.
            if (isRandomPartitionType)
            {
                stringPartitions = (RandGen.Next() % 2) == 0; // decide if we have string or int64 partitions
            }
            else
            {
                if (type == PartitionKeyType.StringKey)
                {
                    stringPartitions = true;
                }
            }

            for (int i = 0; i < partitionCount; i++)
            {
                PartitionRecord newPartition;

                if (stringPartitions)
                {
                    // string partition key
                    string partitionKey = i.ToString(CultureInfo.InvariantCulture);
                    newPartition = new PartitionRecord(
                        instanceName,
                        PartitionKeyType.StringKey,
                        partitionKey,
                        new IntegerPartitionKeyRange());

                    instance.Partitions[i] = newPartition;
                    LogHelper.Log("Created; Instance: {0} StringPartition: {1}", instanceName, partitionKey);
                }
                // numerical partition key -- single number range
                IntegerPartitionKeyRange partitionInt64Key = new IntegerPartitionKeyRange
                {
                    IntegerKeyLow  = i * int64PartitionKeyLowValMultiplier,
                    IntegerKeyHigh = i * int64PartitionKeyLowValMultiplier + (RandGen.Next() % (int64PartitionKeyLowValMultiplier - 1))
                };

                newPartition = new PartitionRecord(
                    instanceName,
                    PartitionKeyType.Int64Key,
                    null,
                    partitionInt64Key);

                instance.Partitions[i] = newPartition;
                LogHelper.Log("Created; Instance: {0} Int64Partition: {1}-{2}", instanceName, partitionInt64Key.IntegerKeyLow, partitionInt64Key.IntegerKeyHigh);
            }
        }
Пример #8
0
        /// <summary>
        /// Setup a session from source partition to target partition.
        /// </summary>
        /// <param name="sessionTest"></param>
        /// <param name="sourcePartition"></param>
        /// <param name="targetPartition"></param>
        private void SetupSessionTest(SessionTest sessionTest, PartitionRecord sourcePartition, PartitionRecord targetPartition)
        {
            VS.Assert.IsFalse(sourcePartition == targetPartition,
                              "sourcePartition {0} equals targetPartition {1} in SetupSessionTests", sourcePartition, targetPartition);

            IReliableSessionManager sourceSessionManager = sourcePartition.SessionManager;
            Uri    targetSvcInstance = targetPartition.InstanceName;
            string targetEndpoint    = targetPartition.Endpoint;

            Task <IReliableMessagingSession> newOutboundSessionTask = null;
            bool testSkipped = false;

            try
            {
                // Setup the outbound session from source to target partition
                switch (targetPartition.PartitionType)
                {
                case PartitionKeyType.Singleton:
                    newOutboundSessionTask = sourceSessionManager.CreateOutboundSessionAsync(targetSvcInstance,
                                                                                             targetEndpoint, new CancellationToken());
                    break;

                case PartitionKeyType.StringKey:
                    string targetStringKey = targetPartition.StringPartitionPartitionKey;
                    newOutboundSessionTask = sourceSessionManager.CreateOutboundSessionAsync(targetSvcInstance,
                                                                                             targetStringKey, targetEndpoint, new CancellationToken());
                    break;

                case PartitionKeyType.Int64Key:
                    IntegerPartitionKeyRange targetInt64Key = targetPartition.Int64PartitionPartitionKey;
                    long rangeSize             = targetInt64Key.IntegerKeyHigh - targetInt64Key.IntegerKeyLow + 1;
                    long targetPartitionNumber = targetInt64Key.IntegerKeyLow + (RandGen.Next() % rangeSize);
                    newOutboundSessionTask = sourceSessionManager.CreateOutboundSessionAsync(targetSvcInstance,
                                                                                             targetPartitionNumber, targetEndpoint, new CancellationToken());
                    break;
                }

                VS.Assert.IsNotNull(newOutboundSessionTask, "Null newOutboundSessionTask in SetupSessionTests");

                newOutboundSessionTask.Wait();
                sessionTest.OutboundSession = newOutboundSessionTask.Result;
            }
            catch (System.AggregateException e)
            {
                Exception inner = e.InnerException.InnerException;
                VS.Assert.AreEqual(inner.GetType(), typeof(System.Runtime.InteropServices.COMException),
                                   "Unexpected AggregateException {0} from CreateOutboundSessionAsync", inner.GetType().ToString());

                // Due to random nature of source and target selection, it might be possible we create a duplicate selection.
                // in this case, we skip the test.
                System.Runtime.InteropServices.COMException realException =
                    (System.Runtime.InteropServices.COMException)inner;
                uint hresult       = (uint)realException.ErrorCode;
                uint expectedError = (uint)NativeTypes.FABRIC_ERROR_CODE.FABRIC_E_RELIABLE_SESSION_ALREADY_EXISTS;
                VS.Assert.AreEqual(expectedError, hresult,
                                   "Unexpected error HRESULT code {0} from CreateOutboundSessionAsync", hresult);

                testSkipped = true;
                LogHelper.Log("Test# skipped due to {0} exception ", hresult);
            }

            if (testSkipped)
            {
                sessionTest.SkipTest = true;
            }
            else
            {
                // initialize snapshot test and open the session for message communication.
                sessionTest.OutboundSession.OpenAsync(new CancellationToken()).Wait();
                sessionTest.InboundSession = targetPartition.InboundSessions[sourcePartition.PartitionKey];

                sessionTest.SnapshotOutbound = sessionTest.OutboundSession.GetDataSnapshot();
                sessionTest.SnapshotInbound  = sessionTest.InboundSession.GetDataSnapshot();

                VS.Assert.IsFalse(sessionTest.InboundSession == sessionTest.OutboundSession,
                                  "sourcePartition equals targetPartition  in SetupSessionTests");
            }
        }