flowchart LR
subgraph AccelByte Gaming Services
CL[gRPC Client]
end
subgraph Extend Override App
SV["gRPC Server"]
end
CL --- SV
AccelByte Gaming Services
(AGS) features can be customized using
Extend Override
apps. An Extend Override
app is basically a gRPC server
which
contains one or more custom functions which can be called by AGS instead of the
default functions.
This repository provides a project template to create an Extend Override
app for cloudsave validator
written in C#
. It includes an example of how the
custom functions can be implemented. It also includes the essential
gRPC server
authentication and authorization to ensure security. Additionally,
it comes with built-in instrumentation for observability, ensuring that metrics,
traces, and logs are available upon deployment.
You can clone this repository to begin developing your own Extend Override
app for cloudsave validator
. Simply modify this project by implementing
your own logic for the custom functions.
-
Windows 11 WSL2 or Linux Ubuntu 22.04 or macOS 14+ with the following tools installed:
a. Bash
-
On Windows WSL2 or Linux Ubuntu:
bash --version GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu) ...
-
On macOS:
bash --version GNU bash, version 3.2.57(1)-release (arm64-apple-darwin23) ...
b. Make
-
On Windows WSL2 or Linux Ubuntu:
To install from the Ubuntu repository, run
sudo apt update && sudo apt install make
.make --version GNU Make 4.3 ...
-
On macOS:
make --version GNU Make 3.81 ...
c. Docker (Docker Desktop 4.30+/Docker Engine v23.0+)
-
On Linux Ubuntu:
- To install from the Ubuntu repository, run
sudo apt update && sudo apt install docker.io docker-buildx docker-compose-v2
. - Add your user to the
docker
group:sudo usermod -aG docker $USER
. - Log out and log back in to allow the changes to take effect.
- To install from the Ubuntu repository, run
-
On Windows or macOS:
Follow Docker's documentation on installing the Docker Desktop on Windows or macOS.
docker version ... Server: Docker Desktop Engine: Version: 24.0.5 ...
d. .NET 6 SDK
-
On Linux Ubuntu:
To install from the Ubuntu repository, run
sudo apt-get update && sudo apt-get install -y dotnet-sdk-6.0
. -
On Windows or macOS:
Follow Microsoft's documentation for installing .NET on Windows or on macOS.
dotnet --version 6.0.128
e. Curl
-
On Windows WSL2 or Linux Ubuntu:
To install from the Ubuntu repository, run
sudo apt update && sudo apt install curl
.curl --version curl 7.81.0 (x86_64-pc-linux-gnu) ...
-
On macOS:
curl --version curl 8.4.0 (x86_64-apple-darwin23.0) ... ...
f. Jq
-
On Windows WSL2 or Linux Ubuntu:
To install from the Ubuntu repository, run
sudo apt update && sudo apt install jq
.jq --version jq-1.6 ...
-
On macOS:
To install using Homebrew, run
brew install jq
.jq --version jq-1.7.1
g. Postman
- Use the available binary from Postman.
h. ngrok
- Follow ngrok's installation guide.
- Use the available binary from extend-helper-cli.
❗ In macOS, you may use Homebrew to easily install some of the tools above.
-
-
Access to AGS environment.
a. Base URL
- For
Shared Cloud
tier e.g. https://spaceshooter.prod.gamingservices.accelbyte.io - For
Private Cloud
tier e.g. https://dev.accelbyte.io
b. Create a Game Namespace if you don't have one yet. Keep the
Namespace ID
.c. Create an OAuth Client with confidential client type. Keep the
Client ID
andClient Secret
. - For
To be able to run this app, you will need to follow these setup steps.
-
Create a docker compose
.env
file by copying the content of .env.template file.⚠️ The host OS environment variables have higher precedence compared to.env
file variables: If the variables in.env
file do not seem to take effect properly, check if there are host OS environment variables with the same name. See documentation about docker compose environment variables precedence for more details. -
Fill in the required environment variables in
.env
file as shown below.AB_BASE_URL=https://demo.accelbyte.io # Base URL of AccelByte Gaming Services environment AB_CLIENT_ID='xxxxxxxxxx' # Client ID from the Prerequisites section AB_CLIENT_SECRET='xxxxxxxxxx' # Client Secret from the Prerequisites section AB_NAMESPACE='xxxxxxxxxx' # Namespace ID from the Prerequisites section PLUGIN_GRPC_SERVER_AUTH_ENABLED=true # Enable or disable access token validation
❗ In this app, PLUGIN_GRPC_SERVER_AUTH_ENABLED is
true
by default: If it is set tofalse
, thegRPC server
can be invoked without an AGS access token. This option is provided for development purpose only. It is recommended to enablegRPC server
access token validation in production environment.For more options, create
src/AccelByte.PluginArch.CloudsaveValidator.Demo.Server/appsettings.Development.json
and fill in the required configuration.{ "EnableAuthorization": true, // Enable or disable access token and permission check (env var: PLUGIN_GRPC_SERVER_AUTH_ENABLED) "RevocationListRefreshPeriod": 60, "AccelByte": { "BaseUrl": "https://demo.accelbyte.io", // Base URL (env var: AB_BASE_URL) "ClientId": "xxxxxxxxxx", // Client ID (env var: AB_CLIENT_ID) "ClientSecret": "xxxxxxxxxx", // Client Secret (env var: AB_CLIENT_SECRET) "AppName": "CLOUDSAVEGRPCSERVICE", "TraceIdVersion": "1", "Namespace": "xxxxxxxxxx", // Namespace ID (env var: AB_NAMESPACE) "EnableTraceId": true, "EnableUserAgentInfo": true, "ResourceName": "CLOUDSAVEGRPCSERVICE" } }
⚠️ Environment variable values will override related configuration values in this file.
To build this app, use the following command.
make build
The build output will be available in .output
directory.
To (build and) run this app in a container, use the following command.
docker compose up --build
⚠️ To perform the following, make sure PLUGIN_GRPC_SERVER_AUTH_ENABLED is set tofalse
: Otherwise, the gRPC request will be rejected by thegRPC server
.
This app can be tested locally using postman.
-
Run this app by using the command below.
docker compose up --build
-
Open
postman
, create a newgRPC request
, and enterlocalhost:6565
as server URL.⚠️ If you are running grpc-plugin-dependencies stack alongside this project as mentioned in Test Observability: Uselocalhost:10000
instead oflocalhost:6565
. This way, thegRPC server
will be called viaEnvoy
service withingrpc-plugin-dependencies
stack instead of directly. -
Continue by selecting
CloudsaveValidatorService/BeforeWritePlayerRecord
method and invoke it with the sample message below.a. With a VALID
payload
{ "createdAt": { "nanos": 10, "seconds": "1693468029" }, "isPublic": true, "key": "favourite_weapon", "namespace": "mynamespace", "payload": "eyJ1c2VySWQiOiAiMWUwNzZiY2VlNmQxNGM4NDlmZmIxMjFjMGUwMTM1YmUiLCAiZmF2b3VyaXRlV2VhcG9uVHlwZSI6ICJTV09SRCIsICJmYXZvdXJpdGVXZWFwb24iOiAiZXhjYWxpYnVyIn0=", // {"userId": "1e076bcee6d14c849ffb121c0e0135be", "favouriteWeaponType": "SWORD", "favouriteWeapon": "excalibur"} encoded in base64 "setBy": "SERVER", "updatedAt": { "nanos": 10, "seconds": "1693468275" }, "userId": "1e076bcee6d14c849ffb121c0e0135be" }
The response will contain
isSuccess: true
{ "isSuccess": true, "key": "favourite_weapon", "userId": "1e076bcee6d14c849ffb121c0e0135be" }
b. With an INVALID
payload
{ "createdAt": { "nanos": 10, "seconds": "1693468029" }, "isPublic": true, "key": "favourite_weapon", "namespace": "mynamespace", "payload": "eyJmb28iOiJiYXIifQ==", // {"foo":"bar"} encoded in base64 "setBy": "SERVER", "updatedAt": { "nanos": 10, "seconds": "1693468275" }, "userId": "1e076bcee6d14c849ffb121c0e0135be" }
The response will contain
isSuccess: false
{ "isSuccess": false, "key": "favourite_weapon", "userId": "1e076bcee6d14c849ffb121c0e0135be", "error": { "errorCode": 1, "errorMessage": "favourite weapon cannot be empty;favourite weapon type cannot be empty;user ID cannot be empty" } }
For testing this app which is running locally with AGS, the gRPC server
needs to be exposed to the internet. To do this without requiring public IP, we
can use something like ngrok.
-
Run this app by using command below.
docker compose up --build
-
Sign-in/sign-up to ngrok and get your auth token in
ngrok
dashboard. -
In this app root directory, run the following helper command to expose
gRPC server
port in local development environment to the internet. Take a note of thengrok
forwarding URL e.g.http://0.tcp.ap.ngrok.io:xxxxx
.make ngrok NGROK_AUTHTOKEN=xxxxxxxxxxx
⚠️ If you are running grpc-plugin-dependencies stack alongside this app as mentioned in Test Observability: Run the above command ingrpc-plugin-dependencies
directory instead of this app directory. This way, thegRPC server
will be called viaEnvoy
service withingrpc-plugin-dependencies
stack instead of directly. -
Create an OAuth Client with
confidential
client type with the following permissions. Keep theClient ID
andClient Secret
.- For AGS Private Cloud customers:
ADMIN:NAMESPACE:{namespace}:CLOUDSAVE:PLUGINS [CREATE,READ,UPDATE,DELETE]
ADMIN:NAMESPACE:{namespace}:USER:*:CLOUDSAVE:RECORD [CREATE,READ,UPDATE,DELETE]
ADMIN:NAMESPACE:{namespace}:CLOUDSAVE:RECORD [CREATE,READ,UPDATE,DELETE]
NAMESPACE:{namespace}:CLOUDSAVE:RECORD [CREATE,READ,UPDATE,DELETE]
ADMIN:NAMESPACE:{namespace}:INFORMATION:USER:* [DELETE]
- For AGS Shared Cloud customers:
- Cloud Save -> Custom Configuration (Read, Create, Update, Delete)
- Cloud Save -> Game Records (Read, Create, Update, Delete)
- Cloud Save -> Player Records (Read, Create, Update, Delete)
- IAM -> Users (Delete)
⚠️ Oauth Client created in this step is different from the one from Prerequisites section: It is required by demo.sh script in the next step to register thegRPC Server
URL and also to create and delete test users. - For AGS Private Cloud customers:
-
Run the demo.sh script to simulate AGS operation which calls this app using the
Client ID
andClient Secret
created in the previous step. Pay attention this app log in the console when the script is running. The custom functions should get called by AGS.export AB_BASE_URL='https://demo.accelbyte.io' export AB_CLIENT_ID='xxxxxxxxxx' # Use Client ID from the previous step export AB_CLIENT_SECRET='xxxxxxxxxx' # Use Client Secret from the previous step export AB_NAMESPACE='accelbyte' # Use your Namespace ID export GRPC_SERVER_URL='0.tcp.ap.ngrok.io:xxxxx' # Use your ngrok forwarding URL bash demo.sh
⚠️ Make sure demo.sh has Unix line-endings (LF): If this repository was cloned in Windows for example, thedemo.sh
may have Windows line-endings (CRLF) instead. In this case, use tools likedos2unix
to change the line-endings to Unix (LF). Invalid line-endings may cause errors such asdemo.sh: line 2: $'\r': command not found
.
⚠️ Ngrok free plan has some limitations: You may want to use paid plan if the traffic is high.
To be able to see the how the observability works in this app locally, there are few things that need be setup before performing tests.
-
Uncomment loki logging driver in docker-compose.yaml
# logging: # driver: loki # options: # loki-url: http://host.docker.internal:3100/loki/api/v1/push # mode: non-blocking # max-buffer-size: 4m # loki-retries: "3"
⚠️ Make sure to install docker loki plugin beforehand: Otherwise, this project will not be able to run. This is required so that container logs can flow to theloki
service withingrpc-plugin-dependencies
stack. Use this command to install docker loki plugin:docker plugin install grafana/loki-docker-driver:latest --alias loki --grant-all-permissions
. -
Clone and run grpc-plugin-dependencies stack alongside this project. After this, Grafana will be accessible at http://localhost:3000.
git clone https://github.com/AccelByte/grpc-plugin-dependencies.git cd grpc-plugin-dependencies docker-compose up
❗ More information about grpc-plugin-dependencies is available here.
-
Perform testing. For example, by following Test in Local Development Environment or Test with AccelByte Gaming Services.
After done testing, you may want to deploy this app to AccelByte Gaming Services
.
-
Create a new Extend Override App on Admin Portal. Keep the
Repository URI
. -
Download and setup extend-helper-cli (only if it has not been done previously).
-
Perform docker login with
extend-helper-cli
using the following command.extend-helper-cli dockerlogin --namespace <my-game> --app <my-app> --login
❗ For your convenience, the above
extend-helper-cli
command can also be copied fromRepository Authentication Command
under the corresponding app detail page. -
Build and push this project docker image to AccelByte ECR using the following command.
extend-helper-cli image-upload --work-dir <my-project-dir> --namespace <my-game> --app <my-app> --image-tag v0.0.1
⚠️ Make sure to perform docker login (step 3) before executing the above command. -
Open Admin Portal, go to Extend -> Overridable Features. And then select the extend app.
-
To deploy selected image tag, click Image Version History and select desired image tag to be deployed.
-
Click Deploy Image, confirm the deployment and go back to App Detail by clicking Cancel.
-
Wait until app status is running.
Proceed to create your own Extend Override
app for cloudsave validator
by modifying this project. See here for more details.