Skip to content

Latest commit

 

History

History
187 lines (148 loc) · 8.05 KB

a2.md

File metadata and controls

187 lines (148 loc) · 8.05 KB

Assignment 2: Deploy a RESTful Back-end (40 Points)

Due Tuesday Sep 5th at midnight (Late submission are allowed, but there will be a penality of -10 points.)

This assignment is the first step towards building a functional backend for the final project - building a receipt storage and indexing service. The goal of this assignment is to familiarize you with REST architecture, the CircleCI Continuous Integration tool, and the mechanism by which one can deploy software to the cloud.

We will not worry about session management and access control---an user can read / write any receipt. We will not worry about setting up an external database - we will use H2 (which supports the MySQL SQL Dialect).

To complete the assignment you must complete the following:

  1. Configure CircleCI to run on the master branch in your repo
  2. Add a CircleCI build-status badge to README.md
  3. Build a RESTful API that supports operations on receipts and tags
  4. Deploy the API to AWS
  5. Submit

1. Configuring CircleCI

CircleCI is a cloud-based tool for building software. CircleCI seamlessly integrates with GitHub to detect when a change is made, at which point CircleCI will execute a series of build-steps that are defined in the file .circleci/config.yml which must be added to your GitHub repository.

When you initially log into CircleCI you should see a Dashboard showing recent builds.
A Projects menu-option on the left-hand side will help you configure your repo. Choose Add Project, select the repository you want to setup by clicking Setup Project next to your repository name, and finally select the OS (linux), Platform (2.0) and Language (Gradle/Java).

Circle will reward your efforts here by preparing a sample config.yml along with detailed instructions you should follow carefully to get your CI system setup. The sample config.yml will work without modification, however you should not be afraid to dive into the excellent CircleCI Docs to add custom build steps such as building a docker-image.

Once CircleCI is setup, every time you push changes to GitHub CircleCI will detect the change and will follow the steps defined in config.yml. By should always include checking out the new code and running the tests. build.gradle in the skeleton repo is already setup to run any tests that are annotated with @Test. You can check this yourself by running the test target e.g. ./gradlew test.

2. Setting up a CircleCI build status badge

Important - adding your build status badge to README.md in the class GitHub is the only way to get credit for setting up CircleCI. You can get the code for your badge by copying it from the Status Badges section of the Settings page for your project in CircleCI.

To get credit for the assignment you must add the badge as a suffix to your line in the Students section of the README.md, you must write at least one non-trivial test, and CircleCI must run the test + pass.

A working test is available in the skeleton project at src/test/java/api/CreateReceiptRequestTest.java

3. Build a RESTful API

The API we are building is relatively simple, and only supports operations on two resources: receipts and tags. The basic idea is that one should be able to create new receipts, categorize them by using user-defined tags, and retrieve receipts by-tag.

Endpoints required to support this functionality with inputs and outputs are summarized below. All endpoints must return 200/OK if the operation completed successfully.

POST /receipts

Effect: Create a new receipt. Every receipt should have an UNSIGNED INT primary key which is returned by this endpoint. No duplicate detection or uniqueness constraints are required. New receipts are un-tagged.

Request Body:

{
    "merchant": "foo", /* required! */
    "amount": 22.45    /* optional, must be valid decimal if provided */
}

Response:

33  /* <-- this is the id of the newly-created un-tagged receipt */

GET /receipts

Effect: Return a list of all receipts in the system.

Request Body: None

Response:

[
  {
    "id": 5,
    "merchant": "Gerry's Ice Cream",
    "amount": 22.50
  },
  {
    "id": 3,
    "merchant": "Starbux"
  }
]

PUT /tags/{tag}

Effect: Categorize a receipt by tagging it. Tags are simple short character strings that are user-defined, (not pre-defined). To associate a receipt with two tags, this endpoint would need to be executed twice - once for each tag. If a receipt is already tagged with a specific tag (say "t1"), the effect of hitting this endpoint (for "t1") will be to un-tag the receipt for the specific tag, but no other tags will be affected.

Request Body

35  /* <-- this is the id of the receipt to tag / untag */

Response None / no response is required from the server beyond a 200/OK HTTP Response code. To do this using the JAX-RS framework, simply declare your endpoint function to return void. e.g.

@PUT
@Path("/tags/{tag}")
public void toggleTag(@PathParam("tag") String tagName) {
    // <your code here
}

GET /tags/{tag}

Effect: Returns a list of all receipts associated with a tag, an empty list if there are none.

Request Body: None

Response:

[
  {
    "id": 39,
    "merchant": "Coin-Op Laundromat",
    "amount": 2.50
  }
]

GET /netid

Effect: Returns your netid as a string for grading purposes.

Request Body: None

Response:

af494

4. Deploy your Code

You need to build a Docker image containing your compiled application code plus any dependencies. The beauty of Docker is that you can run this image locally to verify it is functioning correctly, and when you deploy it to the cloud it should work in exactly the same way. Beauty is not without pain however:

  1. To build an image you must have docker installed and you need to construct a working Dockerfile. A working example will be made available in the skeleton repo shortly.
  2. Once the image is built you must upload the image to a Docker Repository so that AWS can find and pull the image. Essentially you only need to create an account at hub.docker.com and execute a docker push <tagged_image_name
  3. You must setup an AWS ECS Cluster
  4. You need to create a Task Definition and a Service with the name of your Docker image in the Docker Repository
  5. Test your API. Autograder to follow shortly

Although Amazon has an ECS Tutorial available, I think this fantastic tutorial which walks through all the steps and concepts is much better. You can safely ignore the ELB/ALB load balancing steps.

5. Submit

Create a PR for README.md, modifying your row in the Students section by replacing the URL from the first assignment with the url of your shiny new API.

6. Autograder

Auto-grader for the REST API is up. This is a Python script, and hopefully it will work consistently accross all platforms. How to run?

$ python grade_a2.py <your-url>

Here, <your-url> should be your server url (without the angle brackets), e.g., python grade_a2.py http://localhost:8080. You might need to install a Python library called requests used for making http requests very easily. Installing library in python is simple. You can use pip, a Python package manager, do install request library. pip install requests. You can install pip from https://pip.pypa.io/en/stable/installing/.

UPDATE Added support to check CircleCI badge directly from the Github. Once your PR is approved, you can run python grade_a2.py -github <your-netid>. It will fetch the submitted URL, and the circle CI badge and perform the tests that we will check during grading.