Esempio n. 1
0
        /// <summary>
        /// Fetch's an entity's profile from the PlayFab server
        /// </summary>
        /// <param name="callerEntityToken">The entity token of the entity profile being fetched</param>
        /// <returns>The entity's profile</returns>
        private static async Task <EntityProfileBody> GetEntityProfile(string callerEntityToken, EntityKey entity)
        {
            // Construct the PlayFabAPI URL for GetEntityProfile
            var getProfileUrl = GetServerApiUri("/Profile/GetProfile");

            // Create the get entity profile request
            var profileRequest = new GetEntityProfileRequest
            {
                Entity = entity
            };

            // Prepare the request headers
            var profileRequestContent = new StringContent(PlayFabSimpleJson.SerializeObject(profileRequest));

            profileRequestContent.Headers.Add("X-EntityToken", callerEntityToken);
            profileRequestContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");

            PlayFabJsonSuccess <GetEntityProfileResponse> getProfileResponseSuccess = null;
            GetEntityProfileResponse getProfileResponse = null;

            // Execute the get entity profile request
            using (var profileResponseMessage =
                       await httpClient.PostAsync(getProfileUrl, profileRequestContent))
            {
                using (var profileResponseContent = profileResponseMessage.Content)
                {
                    string profileResponseString = await profileResponseContent.ReadAsStringAsync();

                    // Deserialize the http response
                    getProfileResponseSuccess =
                        PlayFabSimpleJson.DeserializeObject <PlayFabJsonSuccess <GetEntityProfileResponse> >(profileResponseString);

                    // Extract the actual get profile response from the deserialized http response
                    getProfileResponse = getProfileResponseSuccess?.data;
                }
            }

            // If response object was not filled it means there was an error
            if (getProfileResponseSuccess?.data == null || getProfileResponseSuccess?.code != 200)
            {
                throw new Exception($"Failed to get Entity Profile: code: {getProfileResponseSuccess?.code}");
            }

            return(getProfileResponse.Profile);
        }
Esempio n. 2
0
        public static async Task <HttpResponseMessage> ExecuteFunction(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = "CloudScript/ExecuteFunction")] HttpRequest request, ILogger log)
        {
            // Extract the caller's entity token
            string callerEntityToken = request.Headers["X-EntityToken"];

            // Extract the request body and deserialize
            string body = await DecompressHttpBody(request);

            var       execRequest = PlayFabSimpleJson.DeserializeObject <ExecuteFunctionRequest>(body);
            EntityKey entityKey   = null;

            if (execRequest.Entity != null)
            {
                entityKey = new EntityKey
                {
                    Id   = execRequest.Entity?.Id,
                    Type = execRequest.Entity?.Type
                };
            }

            // Create a FunctionContextInternal as the payload to send to the target function
            var functionContext = new FunctionContextInternal
            {
                CallerEntityProfile        = await GetEntityProfile(callerEntityToken, entityKey),
                TitleAuthenticationContext = new TitleAuthenticationContext
                {
                    Id          = Environment.GetEnvironmentVariable(TITLE_ID, EnvironmentVariableTarget.Process),
                    EntityToken = await GetTitleEntityToken()
                },
                FunctionArgument = execRequest.FunctionParameter
            };

            // Serialize the request to the azure function and add headers
            var functionRequestContent = new StringContent(PlayFabSimpleJson.SerializeObject(functionContext));

            functionRequestContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");

            var azureFunctionUri = ConstructLocalAzureFunctionUri(execRequest.FunctionName, request.Host);

            var sw = new Stopwatch();

            sw.Start();

            // Execute the local azure function
            using (var functionResponseMessage =
                       await httpClient.PostAsync(azureFunctionUri, functionRequestContent))
            {
                sw.Stop();
                long executionTime = sw.ElapsedMilliseconds;

                if (!functionResponseMessage.IsSuccessStatusCode)
                {
                    throw new Exception($"An error occured while executing the target function locally: FunctionName: {execRequest.FunctionName}, HTTP Status Code: {functionResponseMessage.StatusCode}.");
                }

                // Extract the response content
                using (var functionResponseContent = functionResponseMessage.Content)
                {
                    // Prepare a response to reply back to client with and include function execution results
                    var functionResult = new ExecuteFunctionResult
                    {
                        FunctionName              = execRequest.FunctionName,
                        FunctionResult            = await ExtractFunctionResult(functionResponseContent),
                        ExecutionTimeMilliseconds = (int)executionTime,
                        FunctionResultTooLarge    = false
                    };

                    // Reply back to client with final results
                    var output = new PlayFabJsonSuccess <ExecuteFunctionResult>
                    {
                        code   = 200,
                        status = "OK",
                        data   = functionResult
                    };
                    // Serialize the output and return it
                    var outputStr = PlayFabSimpleJson.SerializeObject(output);

                    return(new HttpResponseMessage
                    {
                        Content = new ByteArrayContent(CompressResponseBody(output, request)),
                        StatusCode = HttpStatusCode.OK
                    });
                }
            }
        }
Esempio n. 3
0
        public static async Task <HttpResponseMessage> Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = "CloudScript/ExecuteFunction")] HttpRequest request, ILogger log)
        {
            // Extract the caller's entity token
            string callerEntityToken = request.Headers["X-EntityToken"];

            // Extract the request body and deserialize
            StreamReader reader = new StreamReader(request.Body);
            string       body   = await reader.ReadToEndAsync();

            ExecuteFunctionRequest execRequest = PlayFabSimpleJson.DeserializeObject <ExecuteFunctionRequest>(body);

            // Grab the title entity token for authentication
            var titleEntityToken = await GetTitleEntityToken();

            var argumentsUri = GetArgumentsUri();

            // Prepare the `Get Arguments` request
            var contextRequest = new GetArgumentsForExecuteFunctionRequest
            {
                AuthenticationContext = new PlayFabAuthenticationContext
                {
                    EntityToken = titleEntityToken
                },
                CallingEntity = callerEntityToken,
                Request       = execRequest
            };

            // Execute the arguments request
            PlayFabResult <GetArgumentsForExecuteFunctionResult> getArgsResponse =
                await PlayFabCloudScriptAPI.GetArgumentsForExecuteFunctionAsync(contextRequest);

            // Validate no errors on arguments request
            if (getArgsResponse.Error != null)
            {
                throw new Exception("Failed to retrieve functions argument");
            }

            // Extract the request for the next stage from the get arguments response
            EntityRequest entityRequest = getArgsResponse?.Result?.Request;

            // Assemble the target function's path in the current App
            string routePrefix  = GetHostRoutePrefix();
            string functionPath = routePrefix != null ? routePrefix + "/" + execRequest.FunctionName
                : execRequest.FunctionName;

            // Build URI of Azure Function based on current host
            var uriBuilder = new UriBuilder
            {
                Host = request.Host.Host,
                Port = request.Host.Port ?? 80,
                Path = functionPath
            };

            // Serialize the request to the azure function and add headers
            var functionRequestContent = new StringContent(PlayFabSimpleJson.SerializeObject(entityRequest));

            functionRequestContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");

            var sw = new Stopwatch();

            sw.Start();

            // Execute the local azure function
            using (var client = new HttpClient())
            {
                using (HttpResponseMessage functionResponseMessage =
                           await client.PostAsync(uriBuilder.Uri.AbsoluteUri, functionRequestContent))
                {
                    sw.Stop();
                    double executionTime = sw.ElapsedMilliseconds;

                    // Extract the response content
                    using (HttpContent functionResponseContent = functionResponseMessage.Content)
                    {
                        string functionResponseString = await functionResponseContent.ReadAsStringAsync();

                        // Prepare a response to reply back to client with and include function execution results
                        var functionResult = new ExecuteFunctionResult
                        {
                            FunctionName         = execRequest.FunctionName,
                            FunctionResult       = PlayFabSimpleJson.DeserializeObject(functionResponseString),
                            ExecutionTimeSeconds = executionTime
                        };

                        // Reply back to client with final results
                        var output = new PlayFabJsonSuccess <ExecuteFunctionResult>
                        {
                            code   = 200,
                            status = "OK",
                            data   = functionResult
                        };
                        var outputStr = PlayFabSimpleJson.SerializeObject(output);
                        return(new HttpResponseMessage
                        {
                            Content = new StringContent(outputStr, Encoding.UTF8, "application/json"),
                            StatusCode = HttpStatusCode.OK
                        });
                    }
                }
            }
        }