Skip to content

Latest commit

 

History

History
266 lines (212 loc) · 12.1 KB

INSTRUCTIONS.md

File metadata and controls

266 lines (212 loc) · 12.1 KB

CloudBowl Instructions

Ever been in a snowball fight where you move around and playfully throw snowballs at others? If not, try it someday! But now instead of risking getting physically smacked, you can build a small, network accessible service (a microservice) that will take part in an epic battle throwing snowballs or other objects at other microservices.

You might be wondering... But how does a microservice "throw" a snowball at other microservices? A microservice can receive network requests (usually over HTTP) and return responses. There is an "arena manager" that will send your microservice the current state of the arena and then your microservice will respond with a command specifying what to do.

Of course the goal is to win, but along the way you'll learn about building and deploying microservices on Google Cloud.

How It Works

You will build a microservice with any technology you want (or start from Java, Kotlin, Scala, Go, Node.js, or Python examples) and then deploy the microservice on Google Cloud. Once deployed, you'll send a pull request to the arena of your choice and once merged your microservice will be added to the arena.

About once a second our arena manager will call your microservice, sending the current arena state (where the players are), and your microservice will respond with a command for what to do. In the arena you can move forward, turn left or right, or throw the object (which is different for each arena). A thrown object will travel up to three spaces in the direction the player is facing. If the object "hits" another player, the thrower gets one point and the hit player loses a point. The arena size is auto-adjusted for the current number of players.

Here is how the arena looks with three made-up players:

Revolving Conflicts

In the arena it is possible that multiple players try to perform conflicting actions. For instance, two players might try to move to the same space or throw objects at each other. In the case of a conflict, the microservice with the quickest response time wins.

Battle API

In order to work with our arena manager, your microservice will need to implement a specific API to participate in the arena. The arena manager will send the current arena state in an HTTP POST to the URL you provide us, with the following JSON structure:

{
  "_links": {
    "self": {
      "href": "https://YOUR_SERVICE_URL"
    }
  },
  "arena": {
    "dims": [4,3], // width, height
    "state": {
      "https://A_PLAYERS_URL": {
        "x": 0, // zero-based x position, where 0 = left
        "y": 0, // zero-based y position, where 0 = top
        "direction": "N", // N = North, W = West, S = South, E = East
        "wasHit": false,
        "score": 0
      }
      ... // also you and the other players
    }
  }
}

Your HTTP response must be status code 200 (OK) with a response body containing your next move, encoded as a single uppercase character of either:

F <- move Forward
R <- turn Right
L <- turn Left
T <- Throw

That's all there is to it! Let's walk through deploying a microservice on Cloud Run, a Google Cloud service for running microservices and other applications.

Deploying Your Microservice

You can build your microservice with any technology and deploy it anywhere as long as it is reachable publicly and conforms to the Battle API. To make things easy you can start with a sample project that just picks a random command.

Pick Your Sample To Start With

There are a number of battle microservice samples you can start from:

Sample Source Deploy
Java & Spring Boot Source Deploy
Java & Quarkus Source Deploy
Kotlin & Spring Boot Source Deploy
Kotlin & Micronaut Source Deploy
Kotlin & Quarkus Source Deploy
Scala & Play Framework Source Deploy
Go Source Deploy
Node.js Source Deploy
Python Source Deploy

After you decide which sample to start with, click the "Run on Google Cloud" button above. This will launch Cloud Shell (a web-based console to a virtual machine in the cloud) where the source will be cloned, then built into a deployable package (a docker container image), which is then uploaded to the Google Container Registry, and then deployed on Cloud Run.

When asked, specify the us-central1 region.

Verify the microservice works

In Cloud Shell you can make a request to your newly deployed microservice, replacing YOUR_SERVICE_URL with the URL for your service (which is in Cloud Shell after the "Your application is now live here" line):

curl -d '{
  "_links": {
    "self": {
      "href": "https://foo.com"
    }
  },
  "arena": {
    "dims": [4,3],
    "state": {
      "https://foo.com": {
        "x": 0,
        "y": 0,
        "direction": "N",
        "wasHit": false,
        "score": 0
      }
    }
  }
}' -H "Content-Type: application/json" -X POST -w "\n" \
  https://YOUR_SERVICE_URL

You should see the response string of either F, L, R, or T.

Request Inclusion in the Arena

To be included in an arena, check out the arena list and pull request instructions.

Make & Deploy Changes

Before you can make changes you need to setup some information in Cloud Shell about the GCP project and the sample you used. First list your GCP projects:

gcloud projects list

You likely only have one project. Copy the PROJECT_ID from the first column and paste it into the following command (replacing YOUR_PROJECT_ID with your actual Project ID), in order to set an environment variable that we will use in later commands:

export PROJECT_ID=YOUR_PROJECT_ID

Now set another environment variable for the sample you used so in later commands we can specify the correct directory and service name:

# Copy and paste ONLY ONE of these
export SAMPLE=java-springboot
export SAMPLE=java-quarkus
export SAMPLE=kotlin-springboot
export SAMPLE=kotlin-micronaut
export SAMPLE=kotlin-quarkus
export SAMPLE=scala-play
export SAMPLE=go
export SAMPLE=nodejs
export SAMPLE=python

Now, you can edit the source for your microservice from within Cloud Shell. To open the Cloud Shell web-based editor, run this command:

cloudshell edit cloudbowl-microservice-game/samples/$SAMPLE/README.md

You will then see further instructions for making changes.

After saving your changes you can build and start the service inside Cloud Shell by following the instructions in the sample's README. After starting the service, test it with:

curl -d '{
  "_links": {
    "self": {
      "href": "https://foo.com"
    }
  },
  "arena": {
    "dims": [4,3],
    "state": {
      "https://foo.com": {
        "x": 0,
        "y": 0,
        "direction": "N",
        "wasHit": false,
        "score": 0
      }
    }
  }
}' -H "Content-Type: application/json" -X POST -w "\n" \
  http://localhost:8080

To deploy your new version, use CNCF Buildpacks via the pack command to create a container image:

pack build gcr.io/$PROJECT_ID/$SAMPLE \
  --path ~/cloudbowl-microservice-game/samples/$SAMPLE \
  --builder heroku/buildpacks

Now that your container image has been created, use the docker command (in Cloud Shell) to push the container image to the Google Container Registry so that it can then be accessed by Cloud Run:

docker push gcr.io/$PROJECT_ID/$SAMPLE

Now deploy the new version on Cloud Run:

gcloud run deploy $SAMPLE\
          --project=$PROJECT_ID\
          --platform=managed\
          --region=us-central1\
          --image=gcr.io/$PROJECT_ID/$SAMPLE\
          --allow-unauthenticated

Now the arena will use your new version!

Develop Locally (Optional)

If you'd like to develop locally on your machine, follow these steps:

  1. First zip up the sample in Cloud Shell:

    cd ~/cloudbowl-microservice-game/samples; zip -r cloudbowl-sample.zip $SAMPLE
    
  2. Then while still in Cloud Shell, download the zip file to your machine:

    cloudshell download-file cloudbowl-sample.zip
    

Now complete the rest of these steps on your machine...

  1. Install the gcloud CLI

  2. Login to Google Cloud:

    gcloud auth login
    
  3. Unzip the downloaded file and then make & test your changes using the instructions in the README.

  4. Set the environment variables PROJECT_ID and SAMPLE to the same values as in Cloud Shell.

  5. Use Cloud Build to build the container (from the root project directory):

    gcloud alpha builds submit . --pack=builder=heroku/buildpacks,image=gcr.io/$PROJECT_ID/$SAMPLE
    
  6. Deploy the new container:

    gcloud run deploy $SAMPLE\
              --project=$PROJECT_ID\
              --platform=managed\
              --region=us-central1\
              --image=gcr.io/$PROJECT_ID/$SAMPLE\
              --allow-unauthenticated
    

Congratulations

Congratulations, you've successfully built and deployed a microservice that can battle with other microservices! Good luck!