public PartitionWrapper(Partition partition, Guid primaryPartitionId, Uri applicationName, Uri serviceName, ClusterDetails primaryCluster, ClusterDetails secondaryCluster) { this.partitionId = partition.PartitionInformation.Id; this.primaryPartitionId = primaryPartitionId; this.PartitionInformation = partition.PartitionInformation; this.ServiceKind = partition.ServiceKind; this.HealthState = partition.HealthState; this.PartitionStatus = partition.PartitionStatus; this.applicationName = applicationName; this.serviceName = serviceName; this.primaryCluster = primaryCluster; this.secondaryCluster = secondaryCluster; }
// An interface method which is called by the webservice to configure the applications for stanby in secondary cluster // Takes in list of applications to be configured and corresponding policies and maps the partitions public async Task Configure(List <string> applications, List <PolicyStorageEntity> policyDeatils, ClusterDetails primaryCluster, ClusterDetails secondaryCluster) { IReliableDictionary <Guid, PartitionWrapper> myDictionary = await this.StateManager.GetOrAddAsync <IReliableDictionary <Guid, PartitionWrapper> >("partitionDictionary"); IPolicyStorageService policyStorageClient = ServiceProxy.Create <IPolicyStorageService>(new Uri("fabric:/SFAppDRTool/PolicyStorageService")); bool stored = await policyStorageClient.PostStorageDetails(policyDeatils, primaryCluster.address + ':' + primaryCluster.httpEndpoint); foreach (string application in applications) { await MapPartitionsOfApplication(new Uri("fabric:/" + application), primaryCluster, secondaryCluster, "partitionDictionary"); } }
// Maps Int64 partitions based on their low key public async Task MapInt64Partitions(Uri applicationName, Uri serviceName, ClusterDetails primaryCluster, ServicePartitionList primaryPartitions, ClusterDetails secondaryCluster, ServicePartitionList secondaryPartitions, string partitionDictionaryName) { IReliableDictionary <String, PartitionWrapper> partitionDictionary = await this.StateManager.GetOrAddAsync <IReliableDictionary <String, PartitionWrapper> >(partitionDictionaryName); foreach (var primaryPartition in primaryPartitions) { long hashCode = HashUtil.getLongHashCode(primaryPartition.PartitionInformation.Id.ToString()); if (await BelongsToPartition(hashCode)) { var int64PartitionInfo = primaryPartition.PartitionInformation as Int64RangePartitionInformation; long?lowKeyPrimary = int64PartitionInfo?.LowKey; foreach (var secondaryPartition in secondaryPartitions) { long?lowKeySecondary = (secondaryPartition.PartitionInformation as Int64RangePartitionInformation)?.LowKey; if (lowKeyPrimary == lowKeySecondary) { using (var tx = this.StateManager.CreateTransaction()) { var result = await partitionDictionary.TryAddAsync(tx, Utility.getPartitionAccessKey(primaryPartition.PartitionInformation.Id, primaryCluster.address, secondaryCluster.address), new PartitionWrapper(secondaryPartition, primaryPartition.PartitionInformation.Id, applicationName, serviceName, primaryCluster, secondaryCluster)); ServiceEventSource.Current.ServiceMessage(this.Context, result ? "Successfully Mapped Partition-{0} to Partition-{1}" : "Already Exists", primaryPartition.PartitionInformation.Id, secondaryPartition.PartitionInformation.Id); await tx.CommitAsync(); } } } } } }
// Maps singleton partitions public async Task MapSingletonPartition(Uri applicationName, Uri serviceName, ClusterDetails primaryCluster, ServicePartitionList primaryPartitions, ClusterDetails secondaryCluster, ServicePartitionList secondaryPartitions, string partitionDictionaryName) { IReliableDictionary <String, PartitionWrapper> partitionDictionary = await this.StateManager.GetOrAddAsync <IReliableDictionary <String, PartitionWrapper> >(partitionDictionaryName); using (var tx = this.StateManager.CreateTransaction()) { var result = await partitionDictionary.TryAddAsync(tx, Utility.getPartitionAccessKey(primaryPartitions[0].PartitionInformation.Id, primaryCluster.address, secondaryCluster.address), new PartitionWrapper(secondaryPartitions[0], primaryPartitions[0].PartitionInformation.Id, applicationName, serviceName, primaryCluster, secondaryCluster)); ServiceEventSource.Current.ServiceMessage(this.Context, result ? "Successfully Mapped Partition-{0} to Partition-{1}" : "Already Exists", primaryPartitions[0].PartitionInformation.Id, secondaryPartitions[0].PartitionInformation.Id); // If an exception is thrown before calling CommitAsync, the transaction aborts, all changes are // discarded, and nothing is saved to the secondary replicas. await tx.CommitAsync(); } }
public async Task MapPartitions(Uri applicationName, Uri serviceName, ClusterDetails primaryCluster, ServicePartitionList partitionsInPrimary, ClusterDetails secondaryCluster, ServicePartitionList partitionsInSecondary, string partitionDictionaryName) { if (partitionsInPrimary != null) { ServicePartitionKind partitionKind = partitionsInPrimary[0].PartitionInformation.Kind; if (partitionKind.Equals(ServicePartitionKind.Int64Range)) { await MapInt64Partitions(applicationName, serviceName, primaryCluster, partitionsInPrimary, secondaryCluster, partitionsInSecondary, partitionDictionaryName); } else if (partitionKind.Equals(ServicePartitionKind.Named)) { await MapNamedPartitions(applicationName, serviceName, primaryCluster, partitionsInPrimary, secondaryCluster, partitionsInSecondary, partitionDictionaryName); } else if (partitionKind.Equals(ServicePartitionKind.Singleton)) { await MapSingletonPartition(applicationName, serviceName, primaryCluster, partitionsInPrimary, secondaryCluster, partitionsInSecondary, partitionDictionaryName); } } }
public async Task MapPartitionsOfService(Uri applicationName, Uri serviceName, ClusterDetails primaryCluster, ClusterDetails secondaryCluster, String partitionDictionaryName) { FabricClient primaryFabricClient = Utility.GetFabricClient(primaryCluster.clientConnectionEndpoint, primaryCluster.certificateThumbprint, primaryCluster.commonName); FabricClient secondaryFabricClient = Utility.GetFabricClient(secondaryCluster.clientConnectionEndpoint, secondaryCluster.certificateThumbprint, secondaryCluster.commonName); ServicePartitionList primaryPartitions = await primaryFabricClient.QueryManager.GetPartitionListAsync(serviceName); ServicePartitionList secondaryPartitions = await secondaryFabricClient.QueryManager.GetPartitionListAsync(serviceName); await MapPartitions(applicationName, serviceName, primaryCluster, primaryPartitions, secondaryCluster, secondaryPartitions, partitionDictionaryName); }
// Maps the paritions of the applications from primary cluster and secondary cluster public async Task MapPartitionsOfApplication(Uri applicationName, ClusterDetails primaryCluster, ClusterDetails secondaryCluster, String partitionDictionaryName) { FabricClient primaryFabricClient = Utility.GetFabricClient(primaryCluster.clientConnectionEndpoint, primaryCluster.certificateThumbprint, primaryCluster.commonName); FabricClient secondaryFabricClient = Utility.GetFabricClient(secondaryCluster.clientConnectionEndpoint, secondaryCluster.certificateThumbprint, secondaryCluster.commonName); ServiceList services = await primaryFabricClient.QueryManager.GetServiceListAsync(applicationName); foreach (Service service in services) { ServicePartitionList primaryPartitions; ServicePartitionList secondaryPartitions; if (service.ServiceKind == ServiceKind.Stateless) { continue; } try { primaryPartitions = await primaryFabricClient.QueryManager.GetPartitionListAsync(service.ServiceName); } catch (Exception ex) { ServiceEventSource.Current.Message("Restore Service: Exception getting primary partitions {0}", ex); throw; } try { secondaryPartitions = await secondaryFabricClient.QueryManager.GetPartitionListAsync(service.ServiceName); } catch (Exception ex) { ServiceEventSource.Current.Message("Restore Service: Exception getting secondary partitions {0}", ex); throw; } await MapPartitions(applicationName, service.ServiceName, primaryCluster, primaryPartitions, secondaryCluster, secondaryPartitions, partitionDictionaryName); } }
public async Task ConfigureService(String applicationName, String serviceName, List <PolicyStorageEntity> policyDetails, ClusterDetails primaryCluster, ClusterDetails secondaryCluster) { IPolicyStorageService policyStorageClient = ServiceProxy.Create <IPolicyStorageService>(new Uri("fabric:/SFAppDRTool/PolicyStorageService")); bool overwritePolicyDetails = false; bool stored = await policyStorageClient.PostStorageDetails(policyDetails, primaryCluster.httpEndpoint, primaryCluster.certificateThumbprint, overwritePolicyDetails); await MapPartitionsOfService(new Uri(applicationName), new Uri(serviceName), primaryCluster, secondaryCluster, "partitionDictionary"); }
public async Task ConfigureApplication(string application, List <PolicyStorageEntity> policyDetails, ClusterDetails primaryCluster, ClusterDetails secondaryCluster) { IPolicyStorageService policyStorageClient = ServiceProxy.Create <IPolicyStorageService>(new Uri("fabric:/SFAppDRTool/PolicyStorageService")); bool overwritePolicyDetails = false; bool stored = policyStorageClient.PostStorageDetails(policyDetails, primaryCluster.httpEndpoint, primaryCluster.certificateThumbprint, overwritePolicyDetails).GetAwaiter().GetResult(); await MapPartitionsOfApplication(new Uri(application), primaryCluster, secondaryCluster, "partitionDictionary"); IReliableDictionary <String, List <String> > configuredApplicationsDictionary = await this.StateManager.GetOrAddAsync <IReliableDictionary <String, List <String> > >("configuredApplicationsDictionary"); using (var tx = this.StateManager.CreateTransaction()) { String primarySecondaryJoin = Utility.getPrimarySecondaryClusterJoin(primaryCluster.address, secondaryCluster.address); ConditionalValue <List <String> > applicationsList = await configuredApplicationsDictionary.TryGetValueAsync(tx, primarySecondaryJoin); if (applicationsList.HasValue) { List <String> configuredApplicationsList = applicationsList.Value; configuredApplicationsList.Add(application); var result = await configuredApplicationsDictionary.TryAddAsync(tx, primarySecondaryJoin, configuredApplicationsList); } else { List <String> configuredApplicationsList = new List <String>(); configuredApplicationsList.Add(application); var result = await configuredApplicationsDictionary.TryAddAsync(tx, primarySecondaryJoin, configuredApplicationsList); } await tx.CommitAsync(); } }