Skip to content

Commit

Permalink
inital code commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Xiang Shen committed Nov 16, 2018
1 parent 454fe85 commit 7079d2a
Show file tree
Hide file tree
Showing 12 changed files with 509 additions and 2 deletions.
13 changes: 13 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
source 'http://rubygems.org'

gem 'sinatra'
gem 'json'
gem 'rack'
gem 'rack-contrib'
gem 'aws-record'

# These are the dependencies that are used only for unit tests.
group :test do
gem "rspec"
gem "rack-test"
end
61 changes: 61 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
GEM
remote: http://rubygems.org/
specs:
aws-eventstream (1.0.1)
aws-partitions (1.114.0)
aws-record (2.1.2)
aws-sdk-dynamodb (~> 1.0)
aws-sdk-core (3.38.0)
aws-eventstream (~> 1.0)
aws-partitions (~> 1.0)
aws-sigv4 (~> 1.0)
jmespath (~> 1.0)
aws-sdk-dynamodb (1.16.0)
aws-sdk-core (~> 3, >= 3.26.0)
aws-sigv4 (~> 1.0)
aws-sigv4 (1.0.3)
diff-lcs (1.3)
jmespath (1.4.0)
json (2.1.0)
mustermann (1.0.3)
rack (2.0.6)
rack-contrib (2.1.0)
rack (~> 2.0)
rack-protection (2.0.4)
rack
rack-test (1.1.0)
rack (>= 1.0, < 3)
rspec (3.8.0)
rspec-core (~> 3.8.0)
rspec-expectations (~> 3.8.0)
rspec-mocks (~> 3.8.0)
rspec-core (3.8.0)
rspec-support (~> 3.8.0)
rspec-expectations (3.8.2)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.8.0)
rspec-mocks (3.8.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.8.0)
rspec-support (3.8.0)
sinatra (2.0.4)
mustermann (~> 1.0)
rack (~> 2.0)
rack-protection (= 2.0.4)
tilt (~> 2.0)
tilt (2.0.8)

PLATFORMS
ruby

DEPENDENCIES
aws-record
json
rack
rack-contrib
rack-test
rspec
sinatra

BUNDLED WITH
1.16.6
87 changes: 85 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,90 @@
## Running Ruby Sinatra on AWS Lambda

Demo code for running Ruby Sinatra on AWS Lambda
This sample code helps get you started with a simple Sinatra web app deployed on AWS Lambda

What's Here
-----------

This sample includes:

* README.md - this file
* Gemfile - Gem requirements for the sample application
* app/config.ru - this file contains configuration for Rack middleware
* app/server.rb - this file contains the code for the sample service
* app/views - this directory has the template files
* spec/ - this directory contains the RSpec unit tests for the sample application
* template.yml - this file contains the description of AWS resources used by AWS
CloudFormation to deploy your infrastructure

Getting Started
---------------

These directions assume you want to develop on your local computer, and not
from the Amazon EC2 instance itself. If you're on the Amazon EC2 instance, the
virtual environment is already set up for you, and you can start working on the
code.

To work on the sample code, you'll need to clone your project's repository to your
local computer. If you haven't, do that first. You can find instructions in the
AWS CodeStar user guide.

1. Install bundle

$ gem install bundle

2. Install Ruby dependencies for this service

$ bundle install

3. Download the Gems to the local vendor directory

$ bundle install --deployment
4. Create the deployment package (note: if you don't have a S3 bucket, you need to create one):

$ aws cloudformation package \
--template-file template.yaml \
--output-template-file serverless-output.yaml \
--s3-bucket { your-bucket-name }
Alternatively, if you have SAM CLI installed, you can run the following command
which will do the same

$ sam package \
--template-file template.yaml \
--output-template-file serverless-output.yaml \
--s3-bucket { your-bucket-name }
5. Deploying your application

$ aws cloudformation deploy --template-file serverless-output.yaml \
--stack-name { your-stack-name } \
--capabilities CAPABILITY_IAM

Or use SAM CLI

$ sam deploy \
--template-file serverless-output.yaml \
--stack-name { your-stack-name } \
--capabilities CAPABILITY_IAM


What Do I Do Next?
------------------

If you have checked out a local copy of your repository you can start making changes to the sample code.

Learn more about Serverless Application Model (SAM) and how it works here: https://github.com/awslabs/serverless-application-model/blob/master/HOWTO.md

AWS Lambda Developer Guide: http://docs.aws.amazon.com/lambda/latest/dg/deploying-lambda-apps.html

How Do I Add Template Resources to My Project?
------------------

To add AWS resources to your project, you'll need to edit the `template.yml`
file in your project's repository. You may also need to modify permissions for
your project's worker roles. After you push the template change, AWS CloudFormation provisions the resources for you.

## License

This library is licensed under the Apache 2.0 License.
This library is licensed under the Apache 2.0 License.
8 changes: 8 additions & 0 deletions app/config.ru
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
require 'rack'
require 'rack/contrib'
require_relative './server'

set :root, File.dirname(__FILE__)
set :views, Proc.new { File.join(root, "views") }

run Sinatra::Application
58 changes: 58 additions & 0 deletions app/server.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
require 'sinatra'
require 'aws-record'

##################################
# For the index page
##################################
get '/' do
erb :index
end

##################################
# Return a Hello world JSON
##################################
get '/hello-world' do
content_type :json
{ :Output => 'Hello World!' }.to_json
end

post '/hello-world' do
content_type :json
{ :Output => 'Hello World!' }.to_json
end

##################################
# Web App with a DynamodDB table
##################################

# Class for DynamoDB table
# This could also be another file you depend on locally.
class FeedbackServerlessSinatraTable
include Aws::Record
string_attr :id, hash_key: true
string_attr :data
epoch_time_attr :ts
end

get '/feedback' do
erb :feedback
end

get '/api/feedback' do
content_type :json
ret = []
items = FeedbackServerlessSinatraTable.scan()
items.each do |r|
item = { :ts => r.ts, :data => r.data }
ret.push(item)
end
ret.sort { |a, b| a[:ts] <=> b[:ts] }.to_json
end

post '/api/feedback' do
content_type :json
body = env["rack.input"].gets
item = FeedbackServerlessSinatraTable.new(id: SecureRandom.uuid, ts: Time.now, data: body)
item.save! # raise an exception if save fails
item.to_json
end
94 changes: 94 additions & 0 deletions app/views/feedback.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<script src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous">
</script>
<link
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
crossorigin="anonymous">
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"
integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
crossorigin="anonymous">
</script>

<script>
$(document).ready(function() {
$("#success-alert").hide();
getAllItems();

$("#feedbackForm").submit(function(e){
e.preventDefault();
let fdata = {}
fdata["name"] = $("#name").val();
fdata["feedback"] = $("#feedback").val();
$.ajax({
cache: false,
url : "/Prod/api/feedback",
type: "POST",
dataType : "json",
data : JSON.stringify(fdata),
success : function(callback){
$("#lists").empty();
getAllItems();
$("#success-alert").alert();
$("#success-alert").fadeTo(2000, 500).slideUp(500, function(){
$("#success-alert").slideUp(500);
});
},
error : function(){
alert("Error to save data");
}
});
});
});

function getAllItems() {
$.ajax({
url: "/Prod/api/feedback"
})
.done(function(json) {
$.each(json, function(i) {
insertListItem(json[i]);
});
});
}
function insertListItem(i) {
let data = JSON.parse(i.data);
let newItem = '<a href="#" class="list-group-item list-group-item-action flex-column align-items-start">' +
'<div class="d-flex w-100 justify-content-between">' +
'<h5 class="mb-1" style="margin:0 auto;">Name: ' + data.name + '</h5>' +
'<small>Time: ' + i.ts + '</small>' +
'</div>' +
'<p class="mb-1">Feedback: ' + data.feedback + '</p></a>';
$("#lists").prepend(newItem);
}

</script>
<div class="jumbotron"
style="background-image: url(https://github.com/awslabs/serverless-application-model/blob/master/aws_sam_introduction.png?raw=true);
background-size: auto 100%;">
</div>
<div class="container">
<div style="text-align: center;">
<h3>Hope you enjoying programming with AWS Lambda! Please share your feedback or any random thoughts.</h3>
</div>

<form action="/Prod/feedback" method="post" id="feedbackForm">
<div class="form-group">
<label for="name">Name:</label>
<input class="form-control" id="name">
</div>
<div class="form-group">
<label for="feedback">Your feedback or any random thoughts here:</label>
<input class="form-control" id="feedback">
</div>
<div class="alert alert-success" id="success-alert">
<strong>Success!</strong> Thank you!
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
<p></p>
<div class="list-group" id="lists"></div>
</div>
8 changes: 8 additions & 0 deletions app/views/index.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<h1>
<div><%= ['Hello', 'Hi', 'Hey', 'Yo'][rand(4)] %> World!</div>
<div><%= ['Hello', 'Hi', 'Hey', 'Yo'][rand(4)] %> World!</div>
</h1>
<div>- from SINATRA on AWS Lambda</div>
<br>
<div>Also checkout the API example: <a href="/Prod/hello-world">Hello World</a></div>
<div>And a web app example: <a href="/Prod/feedback">Feedback</a></div>
9 changes: 9 additions & 0 deletions app/views/layout.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<head><title>Serverless Sinatra</title></head>
<body>

<%= yield %>

</body>
</html>
21 changes: 21 additions & 0 deletions buildspec.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
version: 0.2

phases:
install:
commands:
# Upgrade AWS CLI to the latest version
- pip install --upgrade awscli

# Install Ruby dependencies from the Gemfile.
- bundle install --deployment

build:
commands:
# Run the tests using RSpec.
- rspec

- aws cloudformation package --template template.yaml --s3-bucket $S3_BUCKET --output-template-file template-export.yaml
artifacts:
type: zip
files:
- template-export.yaml
Loading

0 comments on commit 7079d2a

Please sign in to comment.