Esempio n. 1
0
            internal static unsafe ResolvedServiceEndpoint CreateFromNative(IntPtr endpointIntPtr)
            {
                var endpoint       = new ResolvedServiceEndpoint();
                var nativeEndpoint = (NativeTypes.FABRIC_RESOLVED_SERVICE_ENDPOINT *)endpointIntPtr;

                string address = NativeTypes.FromNativeString(nativeEndpoint->Address);

                endpoint.Address = address;

                endpoint.Role = (ServiceEndpointRole)nativeEndpoint->Role;

                return(endpoint);
            }
        private async Task ProcessInputRequest(HttpListenerContext context, CancellationToken cancelRequest)
        {
            String output = null;

            try
            {
                string vin = context.Request.QueryString["vin"];

                // The partitioning scheme of the processing service is a range of integers from 0 - 25.
                // This generates a partition key within that range by converting the first letter of the input name
                // into its numerica position in the alphabet.
                char firstLetterOfLastName = vin.First();
                int  partitionKey          = Char.ToUpper(firstLetterOfLastName) - 'A';

                // Get the Service Partition
                ResolvedServicePartition partition = await this.servicePartitionResolver.ResolveAsync(clientServiceUri, partitionKey, cancelRequest);

                ResolvedServiceEndpoint ep = partition.GetEndpoint();

                JObject addresses             = JObject.Parse(ep.Address);
                string  primaryReplicaAddress = addresses["Endpoints"]["Gateway"].Value <string>();

                string url = primaryReplicaAddress + "api/vehicles/" + vin + "/lock";

                UriBuilder primaryReplicaUriBuilder = new UriBuilder(url);

                string result = await this.httpClient.GetStringAsync(primaryReplicaUriBuilder.Uri);

                output = String.Format(
                    "Result: {0}. Partition key: '{1}' generated from the first letter '{2}' of input value '{3}'.",
                    result,
                    partitionKey,
                    firstLetterOfLastName,
                    vin);
            }
            catch (Exception ex)
            {
                output = ex.Message;
            }

            using (HttpListenerResponse response = context.Response)
            {
                if (output != null)
                {
                    byte[] outBytes = Encoding.UTF8.GetBytes(output);
                    response.OutputStream.Write(outBytes, 0, outBytes.Length);
                }
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Gets the first endpoint from the array of endpoints within a ResolvedServiceEndpoint.
        /// </summary>
        /// <param name="rse">ResolvedServiceEndpoint instance.</param>
        /// <returns>String containing the replica address.</returns>
        /// <exception cref="InvalidProgramException">ResolvedServiceEndpoint address list coudln't be parsed or no endpoints exist.</exception>
        public static string GetFirstEndpoint(this ResolvedServiceEndpoint rse)
        {
            ServiceEndpointCollection sec = null;

            if (ServiceEndpointCollection.TryParseEndpointsString(rse.Address, out sec))
            {
                string replicaAddress;
                if (sec.TryGetFirstEndpointAddress(out replicaAddress))
                {
                    return(replicaAddress);
                }
            }

            throw new InvalidProgramException("ResolvedServiceEndpoint had invalid address");
        }
Esempio n. 4
0
        public async Task <string> GetServiceEndpoint(string cluster, Uri serviceInstanceUri, string serviceEndpointName, CancellationToken token)
        {
            FabricClient fabricClient = this.GetClient(cluster);

            // this resolution may return a stale address if the service moved recently.
            // However, for a single-partition stateless services it shouldn't matter because each instance will publish the same address.
            ResolvedServicePartition rsp = await fabricClient.ServiceManager.ResolveServicePartitionAsync(serviceInstanceUri, this.readOperationTimeout, token);

            ResolvedServiceEndpoint endpoint = rsp.GetEndpoint();

            // This assumes the service uses the Reliable Services framework,
            // where the endpoint is always a JSON object that can contain multiple endpoints.
            JObject endpointJson = JObject.Parse(endpoint.Address);

            return(endpointJson["Endpoints"][serviceEndpointName].Value <string>());
        }
Esempio n. 5
0
            public CommunicationClientCacheEntry <TCommunicationClient> GetOrAddClientCacheEntry(
                ResolvedServiceEndpoint endpoint,
                string listenerName,
                ResolvedServicePartition rsp)
            {
                var key = new PartitionClientCacheKey(endpoint, listenerName);

                return(this.cache.GetOrAdd(
                           key,
                           new CommunicationClientCacheEntry <TCommunicationClient>()
                {
                    Endpoint = endpoint,
                    ListenerName = listenerName,
                    Rsp = rsp
                }));
            }
        private async Task RewriteRequestUriAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var resolver = new ServicePartitionResolver(() => new FabricClient());

            //
            // Resolve service endpoint
            //
            ResolvedServiceEndpoint endpoint = null;

            if (_computePartitionKeyAsLong != null)
            {
                var partition = await resolver.ResolveAsync(_serviceName, _computePartitionKeyAsLong(request), cancellationToken);

                endpoint = partition.Endpoints.First(p => p.Role == ServiceEndpointRole.StatefulPrimary);
            }
            else if (_computePartitionKeyAsString != null)
            {
                var partition = await resolver.ResolveAsync(_serviceName, _computePartitionKeyAsString(request), cancellationToken);

                endpoint = partition.Endpoints.First(p => p.Role == ServiceEndpointRole.StatefulPrimary);
            }
            else
            {
                var partition = await resolver.ResolveAsync(_serviceName, cancellationToken);

                endpoint = partition.Endpoints.First(p => p.Role == ServiceEndpointRole.Stateless);
            }

            //
            // Parse the endpoint
            //
            dynamic address   = JsonConvert.DeserializeObject(endpoint.Address);
            string  urlString = address.Endpoints[""];
            Uri     url       = new Uri(urlString, UriKind.Absolute);

            //
            // Rewrite request URL
            //
            var builder = new UriBuilder(request.RequestUri)
            {
                Scheme = url.Scheme,
                Host   = url.Host,
                Port   = url.Port
            };

            request.RequestUri = builder.Uri;
        }
Esempio n. 7
0
        private async Task <string> ResolveApiAddress()
        {
            //Warning: Very simplistic/optimistic implementation
            //This demo uses only 1 partition. Other stateful services might have more..
            ServicePartitionResolver resolver  = ServicePartitionResolver.GetDefault();
            ResolvedServicePartition partition =
                await resolver.ResolveAsync(
                    new Uri("fabric:/TrafficServiceFabric/TrafficApi"),
                    new ServicePartitionKey(0), CancellationToken.None);

            ResolvedServiceEndpoint endpoint = partition.GetEndpoint();

            JObject addresses = JObject.Parse(endpoint.Address);
            string  address   = (string)addresses["Endpoints"].First();

            return(address);
        }
Esempio n. 8
0
        protected override Task <CommunicationClient> CreateClientAsync(
            ResolvedServiceEndpoint endpoint,
            CancellationToken cancellationToken)
        {
            if (string.IsNullOrEmpty(endpoint.Address) || !endpoint.Address.StartsWith("http"))
            {
                throw new InvalidOperationException("The endpoint address is not valid. Please resolve again.");
            }

            string endpointAddress = endpoint.Address;

            if (!endpointAddress.EndsWith("/"))
            {
                endpointAddress = endpointAddress + "/";
            }

            // Create a communication client. This doesn't establish a session with the server.
            return(Task.FromResult(new CommunicationClient(new Uri(endpointAddress), this.OperationTimeout, this.ReadWriteTimeout)));
        }
Esempio n. 9
0
        public void Constructor_SetClientProperties()
        {
            string listenerName = nameof(Constructor_SetClientProperties);
            ResolvedServiceEndpoint  endpoint  = MockQueryPartitionFactory.CreateResolvedServiceEndpoint(string.Empty);
            ResolvedServicePartition partition = MockQueryPartitionFactory.CreateResolvedServicePartition(
                new Uri("http://localhost"),
                new List <ResolvedServiceEndpoint>());
            Mock <IServiceRemotingClient> clientMock = new Mock <IServiceRemotingClient>();

            clientMock.SetupGet(c => c.ListenerName).Returns(listenerName);
            clientMock.SetupGet(c => c.Endpoint).Returns(endpoint);
            clientMock.SetupGet(c => c.ResolvedServicePartition).Returns(partition);

            ServiceRemotingClientWrapper wrapper = new ServiceRemotingClientWrapper(clientMock.Object);

            Assert.AreEqual(clientMock.Object, wrapper.Client);
            Assert.AreEqual(listenerName, wrapper.ListenerName);
            Assert.AreEqual(endpoint, wrapper.Endpoint);
            Assert.AreEqual(partition, wrapper.ResolvedServicePartition);
        }
Esempio n. 10
0
        /// <summary>
        /// Gets the endpoint from the array of endpoints using the listener name.
        /// </summary>
        /// <param name="rse">ResolvedServiceEndpoint instance.</param>
        /// <param name="name">Listener name.</param>
        /// <returns>String containing the replica address.</returns>
        /// <exception cref="ArgumentException">ResolvedServiceEndpoint address list coudln't be parsed.</exception>
        /// <exception cref="InvalidProgramException">ResolvedServiceEndpoint address list coudln't be parsed.</exception>
        public static string GetEndpoint(this ResolvedServiceEndpoint rse, string name)
        {
            ServiceEndpointCollection sec = null;

            if (ServiceEndpointCollection.TryParseEndpointsString(rse.Address, out sec))
            {
                string replicaAddress;
                if (sec.TryGetEndpointAddress(name, out replicaAddress))
                {
                    return(replicaAddress);
                }
                else
                {
                    throw new ArgumentException(nameof(name));
                }
            }
            else
            {
                throw new InvalidProgramException("ResolvedServiceEndpoint had invalid address");
            }
        }
Esempio n. 11
0
        public async Task <string> GetAPIResult()
        {
            String responseString = string.Empty;

            ResolvedServicePartition mypartition = await resolver.ResolveAsync(serviceUri, new ServicePartitionKey(), new CancellationToken());

            ResolvedServiceEndpoint endpoint = mypartition.GetEndpoint();

            JObject addresses = JObject.Parse(endpoint.Address);
            string  address   = (string)addresses["Endpoints"].First();

            HttpClient          client   = new HttpClient();
            HttpRequestMessage  request  = new HttpRequestMessage(HttpMethod.Get, address + "/api/values");
            HttpResponseMessage response = await client.SendAsync(request);

            if (response.IsSuccessStatusCode)
            {
                responseString = await response.Content.ReadAsStringAsync();
            }

            return(responseString);
        }
Esempio n. 12
0
        /// <summary>
        /// Calls a service endpoint with retries.
        /// </summary>
        /// <typeparam name="TResult">Type of the result.</typeparam>
        /// <param name="rsp">ResolvedServicePartition instance.</param>
        /// <param name="token">CancellationToken instance.</param>
        /// <param name="func">Fucntion to execute, actually makeing the HTTP request.</param>
        /// <returns>Result of the function execution.</returns>
        private async Task <TResult> CallAsync <TResult>(ResolvedServicePartition rsp, CancellationToken token, Func <ResolvedServiceEndpoint, CancellationToken, Task <TResult> > func)
        {
            TResult result = default(TResult);

            // Wrap in a retry policy.
            await _retryPolicy.ExecuteWithRetriesAsync(async (ct) =>
            {
                try
                {
                    ResolvedServiceEndpoint rse = rsp.GetEndpoint();
                    result = await func(rse, ct);
                }
                catch (FabricTransientException)
                {
                    rsp = await GetRspAsync(((Int64RangePartitionInformation)rsp.Info).LowKey, token).ConfigureAwait(false);
                }
                catch (HttpRequestException ex) when((ex.InnerException as WebException)?.Status == WebExceptionStatus.ConnectFailure)
                {
                    rsp = await GetRspAsync(((Int64RangePartitionInformation)rsp.Info).LowKey, token).ConfigureAwait(false);
                }
            }, cancellationToken : token);

            return(result);
        }
Esempio n. 13
0
        public async Task <(bool HasEndPoint, Dictionary <string, string> EndPoint)> GetServiceEndpoint(string serviceName, CancellationToken token)
        {
            var serviceInstanceUri = new Uri(serviceName);

            ResolvedServicePartition rsp = await fabricClient.ServiceManager.ResolveServicePartitionAsync(serviceInstanceUri, this.readOperationTimeout, token);

            ResolvedServiceEndpoint endpoint = rsp.GetEndpoint();

            // This assumes the service uses the Reliable Services framework,
            // where the endpoint is always a JSON object that can contain multiple endpoints.
            JObject endpointJson = JObject.Parse(endpoint.Address);

            if (endpointJson["Endpoints"].HasValues)
            {
                var endpoints = new Dictionary <string, string>();

                endpoints.Add("MCTypeEndpoint", endpointJson["Endpoints"]["MCTypeEndpoint"].Value <string>());
                endpoints.Add("MCrcon", endpointJson["Endpoints"]["MCrcon"].Value <string>());

                return(true, endpoints);
            }

            return(false, new Dictionary <string, string>());
        }
        /// <summary>
        /// Execute the HealthCheck request.
        /// </summary>
        /// <param name="hc">HealthCheck description.</param>
        /// <param name="partition">Partition instance.</param>
        /// <returns>HealthCheck instance.</returns>
        internal async Task <HealthCheck> ExecuteHealthCheckAsync(HealthCheck hc, Partition partition)
        {
            // Check passed parameters.
            if ((null == partition) || (default(HealthCheck) == hc))
            {
                return(default(HealthCheck));
            }

            // Get the service endpoint of the service being tested.
            ResolvedServiceEndpoint rse = await this.GetServiceEndpointAsync(hc.ServiceName, partition);

            if (null == rse)
            {
                return(default(HealthCheck));
            }

            // If an endpoint name was specified, search for that name within the ResolvedServiceEndpoint instance.
            string baseAddress = (string.IsNullOrWhiteSpace(hc.Endpoint)) ? rse.GetFirstEndpoint() : rse.GetEndpoint(hc.Endpoint);
            Uri    uri         = new Uri($"{baseAddress}/{hc.SuffixPath}");

            // Create the HttpRequest message.
            HttpRequestMessage request = this.CreateRequestMessage(hc, uri);

            try
            {
                bool        success = true;
                HealthState hs      = HealthState.Ok;

                // Make the request to the service being tested.
                Stopwatch           sw       = Stopwatch.StartNew();
                HttpResponseMessage response = await this._http.SendAsync(request, HttpCompletionOption.ResponseContentRead, this._token);

                sw.Stop();

                // Evaluate the result of the request. If specific codes were provided, check each of the code arrays to find the result code.
                if ((null != hc.WarningStatusCodes) && (hc.WarningStatusCodes.Contains((int)response.StatusCode)))
                {
                    hs      = HealthState.Warning;
                    success = false;
                }
                else if ((null != hc.ErrorStatusCodes) && (hc.ErrorStatusCodes.Contains((int)response.StatusCode)))
                {
                    hs      = HealthState.Error;
                    success = false;
                }
                else if (false == response.StatusCode.IsSuccessCode())
                {
                    hs      = HealthState.Error;
                    success = false;
                }

                // Report health result to Service Fabric.
                this.Client.HealthManager.ReportHealth(new PartitionHealthReport(hc.Partition, new HealthInformation("Watchdog Health Check", hc.Name, hs)));

                // Report the availability of the tested service to the telemetry provider.
                await
                this._telemetry.ReportAvailabilityAsync(
                    hc.ServiceName.AbsoluteUri,
                    hc.Partition.ToString(),
                    hc.Name,
                    hc.LastAttempt,
                    TimeSpan.FromMilliseconds(hc.Duration),
                    null,
                    success,
                    this._token);

                // Return a new HealthCheck instance containing the results of the request.
                long count = (success) ? 0 : hc.FailureCount + 1;
                return(hc.UpdateWith(DateTime.UtcNow, count, sw.ElapsedMilliseconds, response.StatusCode));
            }
            catch (FabricTransientException ex)
            {
                ServiceEventSource.Current.Exception(ex.Message, ex.GetType().Name, nameof(this.ExecuteHealthCheckAsync));
                return(hc.UpdateWith(DateTime.UtcNow, hc.FailureCount + 1, -1, System.Net.HttpStatusCode.InternalServerError));
            }
            catch (Exception ex)
            {
                ServiceEventSource.Current.Exception(ex.Message, ex.GetType().Name, nameof(this.ExecuteHealthCheckAsync));
                throw;
            }
        }
Esempio n. 15
0
 public PartitionClientCacheKey(ResolvedServiceEndpoint endpoint, string listenerName)
 {
     this.Endpoint     = endpoint;
     this.ListenerName = listenerName;
 }
 private static IReadOnlyDictionary <String, String> DeserializeEndpoints(ResolvedServiceEndpoint partitionEndpoint)
 {
     return(s_javaScriptSerializer.Deserialize <EndpointsCollection>(partitionEndpoint.Address).Endpoints);
 }
Esempio n. 17
0
        public static TestServicePartitionInfo Convert(ResolvedServicePartition resolvedPartition, ResolvedServiceEndpoint resolvedEndpoint, int partitionIdentifierNumber)
        {
            ThrowIf.Null(resolvedPartition, "resolvedPartition");
            ThrowIf.Null(resolvedEndpoint, "resolvedEndpoint");
            ServicePartitionKind keyType = ServicePartitionKind.Invalid;

            object rangeHighKey = null;
            object rangeLowKey  = null;

            switch (resolvedPartition.Info.Kind)
            {
            case ServicePartitionKind.Singleton:
                keyType = ServicePartitionKind.Singleton;
                break;

            case ServicePartitionKind.Int64Range:
                keyType      = ServicePartitionKind.Int64Range;
                rangeHighKey = ((System.Fabric.Int64RangePartitionInformation)resolvedPartition.Info).HighKey;
                rangeLowKey  = ((System.Fabric.Int64RangePartitionInformation)resolvedPartition.Info).LowKey;
                break;

            case ServicePartitionKind.Named:
                keyType = ServicePartitionKind.Named;
                break;

            default:
                throw new InvalidOperationException("Unknown ServicePartitionKind " + resolvedPartition.Info.Kind.ToString() + ".");
            }

            TestServicePartitionInfo testServicePartitionInfo = new TestServicePartitionInfo()
            {
                Location            = resolvedEndpoint.Address,
                Name                = resolvedPartition.ServiceName,
                Id                  = resolvedPartition.Info.Id,
                KeyType             = keyType,
                RangeHighKey        = rangeHighKey,
                RangeLowKey         = rangeLowKey,
                Role                = resolvedEndpoint.Role,
                PartitionIdentifier = partitionIdentifierNumber,
            };

            if (resolvedPartition.Endpoints.Any(e => e.Role == ServiceEndpointRole.StatefulPrimary))
            {
                testServicePartitionInfo.IsPrimaryEndpoint = resolvedPartition.GetEndpoint().Address == resolvedEndpoint.Address;
            }
            else
            {
                testServicePartitionInfo.IsPrimaryEndpoint = false;
            }

            return(testServicePartitionInfo);
        }
 protected override Task <ServiceFabricWebSocketClient> CreateClientAsync(ResolvedServiceEndpoint endpoint, CancellationToken cancellationToken)
 {
     return(Task.FromResult(new ServiceFabricWebSocketClient(endpoint.Address)));
 }
Esempio n. 19
0
        private void QueryPartitionEndpoints(List <BackupEnabledServiceReference> backupEnabledServices, Application app, Service service, Partition partition, ResolvedServiceEndpoint endpoint)
        {
            var endpointJson    = JObject.Parse(endpoint.Address);
            var serviceEndpoint = endpointJson["Endpoints"][BackupRestoreService.BackupRestoreServiceEndpointName];

            if (serviceEndpoint != null)
            {
                string endpointAddress    = serviceEndpoint.Value <string>();
                var    serviceDescription = new BackupEnabledServiceReference
                {
                    ApplicationName         = app.ApplicationName,
                    ServiceName             = service.ServiceName,
                    Int64RangePartitionGuid = partition.PartitionInformation.Id,
                    Endpoint = new Uri(endpointAddress)
                };
                backupEnabledServices.Add(serviceDescription);
            }
        }
 protected override bool ValidateClient(ResolvedServiceEndpoint endpoint, ServiceFabricWebSocketClient client)
 {
     return(client.BaseAddress == endpoint.Address);
 }