text:
# Sinatra API Server Toolbox

I'ts a super-simple API server demo using [sinatra](http://www.sinatrarb.com/).

Let consider this requirements:

- Realize a fast API server, publishing some API endpoints, returning data in JSON format.
- Resources are data already stored in multiple RDBMS database tables, by example from TWO different ALREADY EXISTING (postgreSQL) databases.
- Access data using activerecord ORM, using [sinatra-activerecord gem](https://github.com/janko-m/sinatra-activerecord) that allow to interact with DBs through activerecord ORM.

As proof of concept I supplied some Sinatra endpoints in a pseudo-REST way, a very-very simple authorization key management (just a toy!), some data query and routing, files upload/download.
- Web client tests: I supplied a simple front-end web page using [using jQuery AJAX](https://github.com/solyaris/sinatra-api-server-demo#web-client-side-api-calls-using-jquery-ajax).

To reproduce the Rails developer usual experience:
-  I enjoyed use of [shotgun](https://github.com/rtomayko/shotgun) to automatically reload rack development server (you can so edit source code on the fly, without restart server)!
- I enjoyed also very useful [tux](https://github.com/cldwalker/tux) developement environment, a sortt of a la *rails console* substitute, I mainly used to browse ActiveRecord models and doying queries.
- I display record data set in pretty print data tables using [Hirb](https://github.com/cldwalker/hirb) gem.

# Using ActiveRecord ORM

In this demo application, I want connect with two already living databases (It's the case when you already have in production some *legacy* database and you want to access these data with an API server):

As prrof of concept, I used a real case scenario, where I have a *default/primary* postgreSQL database with name: `esamiAnatomia_development`, that contain three tables:
- `Exam`
- `User`
- `Course`

The source code to connect the database is so simple as:
```ruby
ActiveRecord::Base.establish_connection(ENV['ESAMIANATOMIA_DB_URL'] || \
  'postgres://YOURUSERNAME:YOURPASSWORD@HOSTIPADDRESS/esamiAnatomia_development')

class Exam < ActiveRecord::Base
end
class User < ActiveRecord::Base
end
class Course < ActiveRecord::Base
end
```

Now, let say I want sinatra server be able to connect also to a second different postgreSQL database named `sar`, containing the table:
- `Note`

Here below the table columns details:

```bash
sudo -u db_username psql sar
```
```
psql (9.1.9)
Type "help" for help.

sar=# \d notes
                                     Table "public.notes"
   Column   |            Type             |                     Modifiers
------------+-----------------------------+----------------------------------------------------
 id         | integer                     | not null default nextval('notes_id_seq'::regclass)
 title      | character varying(255)      |
 body       | text                        |
 created_at | timestamp without time zone |
 updated_at | timestamp without time zone |
Indexes:
    "notes_pkey" PRIMARY KEY, btree (id)
```

In that case, the Model is a class where I specify also some ActiveRecord validations:

```ruby
class Note < ActiveRecord::Base
  # connessione a specifico db
  establish_connection(ENV['SAR_DB_URL'] || \
    'postgres://YOURUSERNAME:YOURPASSWORD@HOSTIPADDRESS/sar')

  # set del nome di una tabella, nel caso in cui non sia fatta con convenzione Rails
  self.table_name = "notes"

  # validazioni ActiveRecord
  validates :title, presence: true, length: { minimum: 3 }
  validates :body, presence: true
end
```

# Install and run

- git clone the source code from github
- install all gems specified in Gemfile, with command:
    ```bash
    $ bundle
    ```

- Run the API server in a first terminal
  - set environment variables defining DB URI for both database instances:

    ```bash
    $ export ESAMIANATOMIA_DB_URL=\
    postgres://your-username:your-password@localhost/esamiAnatomia_development
    $ export SAR_DB_URL=\
    postgres://your-username:your-password@localhost/sar
    ```

  - run the API SERVER daemon, by example in development env, with command:
    ```$ shotgun -o localhost```
- Run the API CLIENT calls, using `curl` in a second terminal (below some examples)
- you can monitor/debug ActiveRecord queries running `tux` in a third terminal

# Client side API call examples

Here below I listed some examples of usage of client-side API calls, using `$ curl` command line utility.

## Simplest call

```bash
$ curl localhost:9393/
```

JSON 'pretty printed' reply (is sinatra server is running in developement):

```json
{
  "message": "Sinatra API Server Toolbox"
}
```

JSON 'minified' reply (is sinatra server is running in production):

```json
{"message":"Sinatra API Server Toolbox"}
```

## Passing parameters in request body

```bash
$ curl -X POST localhost:9393/login -d '{ "username":"admin", "password":"admin" }'
```

JSON reply:

```json
{
  "message": "OK: login passed"
}
```

## Authorization token parameter in request header

The example here below show how to manage an Api-key (authorization token).

List of all items of model *users*, passing an _invalid_ key (an UUID, by example):

```bash
$ curl -X GET http://localhost:9393/users -H "key: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
```
JSON reply:

```json
{
  "message": "sorry, you are not authorized."
}
```

List of all items of model *users*, passing a _valid_ key (let say again an UUID):

```bash
$ curl -X GET http://localhost:9393/users -H "key: yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy"
```
JSON reply:

```json
[
  {
    "user": {
      "created_at": "2013-08-27T07:44:48+02:00",
      "crypted_password": "...",
      "login": "Franco Paperone",
      "role": "docente",
      ...
      "updated_at": "2013-08-27T07:44:48+02:00"
    }
  },
  {
    "user": {
      "created_at": "2013-08-27T07:44:48+02:00",
      "crypted_password": "...",
      "login": "admin",
      "role": "admin",
      ...
      "updated_at": "2013-09-25T22:25:38+02:00"
    }
  }
]
```

## DB RESTful CRUD (Create,  Read, Update, Delete)

### CREATE of a new record in table *note*:

```bash
$ curl -X POST http://localhost:9393/notes \
-d '{ "title":"prova", "body":"corpo del messaggio di prova!" }'
```

JSON reply:

```json
{
  "note": {
    "body": "corpo del messaggio di prova!",
    "created_at": "2013-10-20T11:43:59+02:00",
    "id": 1,
    "title": "prova",
    "updated_at": "2013-10-20T11:43:59+02:00"
  }
}
```

### CREATE of a new record in table *note*:

```
$ curl -X POST http://localhost:9393/notes -d '{ "title":"pr", "body":"" }'
```
JSON reply (in case of validation errors):

```json
{
  "title": [
    "is too short (minimum is 3 characters)"
  ],
  "body": [
    "can't be blank"
  ]
}
```

### READ a record from table *note*:

```bash
$ curl -i http://localhost:9393/notes/1
```
JSON reply:
```json
{
  "note": {
    "body": "corpo del messaggio di prova!",
    "created_at": "2013-10-20T11:43:59+02:00",
    "id": 1,
    "title": "prova",
    "updated_at": "2013-10-20T11:43:59+02:00"
  }
}
```

### UPDATE a record from table *note*:
```bash
$ curl -X PUT http://localhost:9393/notes/1 -d '{ "title":"titolo modificato" }'
```

JSON reply:
```json
{
  "note": {
    "body": "corpo del messaggio di prova!",
    "created_at": "2013-10-20T11:43:59+02:00",
    "id": 1,
    "title": "titolo modificato",
    "updated_at": "2013-10-20T11:51:54+02:00"
  }
}

```

### DELETE a record from table *note*:
```bash
$ curl -X DELETE http://localhost:9393/notes/1
```

### List all records from table `note`:
```bash
$ curl http://localhost:9393/notes
```
JSON reply:
```json
[
  {
    "note": {
      "body": "corpo del messaggio di prova 2!",
      "created_at": "2013-10-20T11:55:33+02:00",
      "id": 2,
      "title": "prova 2",
      "updated_at": "2013-10-20T11:55:33+02:00"
    }
  },
  {
    "note": {
      "body": "corpo del messaggio di prova 3!",
      "created_at": "2013-10-20T11:55:46+02:00",
      "id": 3,
      "title": "prova 3",
      "updated_at": "2013-10-20T11:55:46+02:00"
    }
  }
]
```

## Pagination

Get first page (0), assuming a page contain 10 items, from model `Exam`:

```bash
$ curl http://localhost:9393/exams/paginate/10/0
```
JSON reply:
```json
[
  {
    "exam": {
      "id": 1,
      "mail"<EMAIL_ADDRESS>      "matricola": "974146488",
      ...
      "votoanatomia": "",
      "votoistologia": "24"
    }
  },
  {
    "exam": {
      "id": 2,
      "mail"<EMAIL_ADDRESS>      "matricola": "875086984",
      ...
      "votoanatomia": "",
      "votoistologia": ""
    }
  },
  ...
  {
    "exam": {
      "id": 10,
      "mail"<EMAIL_ADDRESS>      "matricola": "748212641",
      ...
      "votoanatomia": "",
      "votoistologia": "26"
    }
  }
]
```

## HTTP Compression

If you're using a Rack-based web framework (as Sinatra) you can very easily slim down your responses by compressing them. To achieve this you just have to use the Rack::Deflater middleware (see `config.ru`). Now any client that sets the `Accept-Encoding: gzip,deflate` header will benefit from smaller responses.

Let consider the GET /exams where the resource JSON representation amount 1650K bytes:

```bash
$ time curl http://<IP_ADDRESS>:9393/exams \
--output exams.json
```
output show an elapsed time of 4.116 seconds:
```
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 1650k  100 1650k    0     0   427k      0  0:00:03  0:00:03 --:--:--  427k

real    0m4.116s
```

If the client sets the `Accept-Encoding: gzip,deflate` header, so the rack server gzip slim down to 198K bytes:

```bash
$ time curl http://<IP_ADDRESS>:9393/exams \
--http1.0 -H "Accept-Encoding: gzip,deflate" \
--output exams.json.gz
```
output show an elapsed time of 4.034 seconds:
```
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  198k    0  198k    0     0  53339      0 --:--:--  0:00:03 --:--:-- 53373

real    0m4.034s
```

Note:
in that case (client and server in localhost) times are similar. Note that data compression (by server) and data decompression (by client) have a cpu cost and there is a time overhead (in comparison to the uncompressed way), But the network payload may decrease so much in case of compression! So the HTTP compression solution could be great in case of low badwith network connections.

## File Upload / Download

Upload file `file.txt` and store the file in /public directory:

```bash
$ curl --upload-file file.txt localhost:9393/upload/
```

Download file `file.txt` stored in /public directory (/public/file.txt):

```bash
$ curl localhost:9393/download/file.txt
```

## Web-client API calls using jQuery AJAX

Here a web demo page: [/public/webclient.html](https://github.com/solyaris/sinatra-api-server-demo/blob/master/public/webclient.html).  Really useful to query database using ActiveRecord methods.

`hirb gem`
allow to show (ActiveRecord returned) record data set in pretty print data tables.

Here below some examples using tux interactive console.

Run the tux console from command prompt:
```bash
$ tux
```

Using tux interactive console with Hirb:

```
Loading development environment (Rack 1.2)

>> require 'hirb'
=> true
>> Hirb.enable
=> true

>> Note
=> Note(id: integer, title: string, body: text, created_at: datetime, updated_at: datetime)

>> Note.all
+----+---------+---------------------------------+---------------------------+---------------------------+
| id | title   | body                            | created_at                | updated_at                |
+----+---------+---------------------------------+---------------------------+---------------------------+
| 2  | prova 2 | corpo del messaggio di prova 2! | 2013-10-20 11:55:33 +0200 | 2013-10-20 11:55:33 +0200 |
| 3  | prova 3 | corpo del messaggio di prova 3! | 2013-10-20 11:55:46 +0200 | 2013-10-20 11:55:46 +0200 |
+----+---------+---------------------------------+---------------------------+---------------------------+
2 rows in set
true

>> Exam.select([:id, :cognomenome, :matricola, :updated_at]).order("updated_at DESC").limit(1)
+------+--------------------+-----------+---------------------------+
| id   | cognomenome        | matricola | updated_at                |
+------+--------------------+-----------+---------------------------+
| 1643 | Aaliyah McCullough | 157560384 | 2013-09-25 22:25:38 +0200 |
+------+--------------------+-----------+---------------------------+
1 row in set
true

>> Exam.find_by_sql('SELECT id, cognomenome, matricola FROM exams ORDER BY updated_at DESC LIMIT 5')
+------+------------------------+-----------+
| id   | cognomenome            | matricola |
+------+------------------------+-----------+
| 1643 | Aaliyah McCullough     | 157560384 |
| 1674 | Aaliyah Harvey PhD     | 538093496 |
| 5000 | Marisa Gibson          | 455246174 |
| 4999 | Wilhelmine Stoltenberg | 403257177 |
| 4998 | Hester Rogahn          | 827819282 |
+------+------------------------+-----------+
5 rows in set
true
```

### Hirb tricks

How to see a table row "vertically" (case of many columns), inside tux, using Hirb:

```
>> Hirb.enable :output => {"ActiveRecord::Base" => { :options => {:vertical => true}}}
>> Exam.find(11)
********************* 1. row *********************
            id: 11
   cognomenome: Mr. Oswaldo Willms
     matricola: 513845379
 votoistologia: 30L
 dataistologia: 26-10-2008
  votoanatomia:
  dataanatomia:
  luogonascita: Augustafurt
   datanascita: 14-09-1981
     cellulare: 539943941
          mail<EMAIL_ADDRESS>          note:
       domande: D1:domanda nr. 1
D2:domandina facile
D3: domanda così così
   corsolaurea: Igiene dentale
          sede: Lake Leanne
annoaccademico: 2013
       docente:
          user: Filippo Adinolfi
    created_at: 2013-08-27 07:45:16 +0200
    updated_at: 2013-08-27 07:45:16 +0200
1 row in set
true
>>
```

# Releases

## v.0.2.0
- HTTP Compression: I added the trick using Rack::Deflate feature. I supplied cleient calls examples.
- JSON load/dump speed-up: I substituted JSON Ruby standard implementation with [MultiJson](https://github.com/intridea/multi_json) gem and super-fast [Oj](https://github.com/ohler55/oj) gem.
- Comments translated in English. Better explanantion in README, inserted an image screenshot of Web Client side API calls example using jQuery AJAX.

# Todo

- Improve authentication key db management.
- Insert an example of managing large amount of data with a super-fast in-memory NOSQL database as [Redis](http://redis.io/)!
- Better manage HTTP return codes
- Better manage error handling
- Exceptions handling lack at all.

# Thanks
- [Iain Barnett](https://github.com/yb66) for his [answer](http://stackoverflow.com/questions/19402318/sinatra-api-server-accessing-preexistent-database-via-activerecord-about-valida/19461374?noredirect=1#19461374) to my stackoverflow.com question.
- [Peter Ohler](https://github.com/ohler55), for his superb gem Oj (fast JSON parser used in this project behind MultiJson).

# License (MIT)

Copyright (c) 2014 Giorgio Robino

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

 IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

# Contact

e-mail<EMAIL_ADDRESS>


text:
# bf2asm
Brainfuck to amd64 assembly compiler

The compiler is written in Go (http://www.golang.com/).
This is an experiment to parse brainfuck into an AST, optimize, and then dump out as amd64.

## Usage:
go build

./bf2asm <file.b> > run.asm

nasm -f elf64 -o run.o run.asm

ld run.o -o run

branch_name: refs/heads/master

extension: md

license_type: permissive


text:
# Supplementary Data Retention Service(SDRS) Deployment
 ## Overview
This document provides recommended SDRS deployment strategy in Google Cloud Platform(GCP) that meets the common
enterprise production requirements for high availability, reliability, and security. The summary of the recommendation is as follows:
* SDRS, a containerized Java server application, is deployed in GCP running on autoscaled Managed Instance Groups(MIG) behind an Internal Load Balancer for availability and reliability.
* The application exposes services through REST API that is managed by Google Endpoints for authentication and authorization.
* All VM instances in MIG and Cloud SQL used by SDRS run on private IP.
* SSL are enabled for HTTP traffic.

## Glossary
 [SDRS](https://github.com/GoogleCloudPlatform/storage-sdrs): Supplementary Data Retention Service

[Managed Instance Group (MIG)](https://cloud.google.com/compute/docs/instance-groups/): A managed instance group is a group of identical instances. You control a managed instance group as a single entity. If you wanted to make changes to instances that are part of a managed instance group, you would make the change to the whole instance group.

[Google Container Registry](https://cloud.google.com/container-registry/): Container Registry is a private container image registry that runs on Google Cloud Platform.

[Google Cloud Storage](https://cloud.google.com/storage/): Cloud Storage allows world-wide storage and retrieval of any amount of data at any time. You can use Cloud Storage for a range of scenarios including serving website content, storing data for archival and disaster recovery, or distributing large data objects to users via direct download.

[Identity and Access Management(IAM)](https://cloud.google.com/iam/) : Cloud IAM, which lets you manage access control by defining who (identity) has what access (role) for which resource. Cloud IAM lets you grant granular access to specific GCP resources and prevent unwanted access to other resources. Cloud IAM lets you adopt the security principle of least privilege, so you grant only the necessary access to your resources.

[Service Account](https://cloud.google.com/iam/docs/service-accounts): A service account is a special Google account that belongs to your application or a virtual machine (VM), instead of to an individual end user. Your application uses the service account to call the Google API of a service, so that the users aren't directly involved.

[Google Cloud SDK](https://cloud.google.com/sdk/): The Cloud SDK is a set of tools for Cloud Platform. It contains gcloud, gsutil, and bq command-line tools, which you can use to access Google Compute Engine, Google Cloud Storage, Google BigQuery, and other products and services from the command-line. You can run these tools interactively or in your automated scripts.

[gcloud](https://cloud.google.com/sdk/gcloud/): The gcloud command-line interface is a tool that provides the primary CLI to Google Cloud Platform. You can use this tool to perform many common platform tasks either from the command-line or in scripts and other automations.

[gsutil](https://cloud.google.com/storage/docs/gsutil): gsutil is a Python application that lets you access Cloud Storage from the command line. It is installed as part of Google Cloud SDK.

[Virtual Private Cloud](https://cloud.google.com/vpc/): Google Cloud Platform (GCP) Virtual Private Cloud (VPC) provides networking functionality to Compute Engine virtual machine (VM)

[Peering](https://cloud.google.com/vpc/docs/vpc-peering): Google Cloud Platform (GCP) Virtual Private Cloud (VPC) Network Peering allows private RFC 1918 connectivity across two VPC networks regardless of whether or not they belong to the same project or the same organization.

[Google Cloud Functions](https://cloud.google.com/functions/): Google Cloud Functions is a lightweight compute solution for developers to create single-purpose, stand-alone functions that respond to Cloud events without the need to manage a server or runtime environment.

[Cloud Function Private VPC connectivity](https://docs.google.com/document/d/1wvLYU21hDGfw3EeisdEq3dVEw9yWBqe9qWmUe4lROXI/edit): This feature lets you connect your Google Cloud Function to resources residing on a VPC network over internal RFC 1918 IP addresses.

[Cloud SQL Private IP Connectivity](https://cloud.google.com/vpc/docs/private-access-options#service-networking): Google CloudSQL support private service access. A private connection is implemented as a VPC Network Peering connection between your VPC network and the service producer's VPC network. The service producer's network is created exclusively for you, and it is not shared with other customers.

## High-level Deployment Architecture
 The separation of SDRS and Client projects are for simple illustration. The [client](../../sample-client/README-cloudfunctions.md) could be deployed in the same project as SDRS is.

![SDRS Deployment Architecture](./images/SDRSDeploymentArchMIG.png)

## Prerequisites
 1. [Google Cloud SDK](https://cloud.google.com/sdk) installed.

## Deployment
 The following sections provide a walkthrough on how to deploy SDRS starting from GCP project creation up to deploying the Endpoints and making updates to the backend software.

### Infrastructure
Basic infrastructure such as project, network, and service accounts need to be provisioned and configured before the
SDRS deployment.

#### 1. Create a GCP Project.
Create a project to deploy SDRS.

    gcloud projects create PROJECT_ID

#### 2. Create Network.

 Create a custom mode VPC via GCP Console or gcloud command. Configure the network based on your requirements

    gcloud compute networks create <YOUR_VPC_NAME> --subnet-mode=custom

#### 3. Create a subnet.
Create a subnet and enable [Private Google Access](https://cloud.google.com/vpc/docs/private-access-options#pga). MIG
uses the subnet and all VM instances in MIG run on private IP only.

    gcloud compute networks subnet create <YOUR_SUBNET_NAME> --network=<YOUR_VPC_NAME> --region=<YOUR_REGION> --range=<YOUR_IP_CIDR_RANGE> --enable-private-ip-google-access

#### 4. Configure [Private Services Access](https://cloud.google.com/vpc/docs/configure-private-services-access) for CloudSQL

 You need to enable Private Services Access in order for CloudSQL to run on private IP.

 Considerations:

 - Select a range that doesn't overlap with existing allocated ranges, subnets, or custom static routes. No two ranges can overlap.
- If you're using an  [auto mode](https://cloud.google.com/vpc/docs/vpc#subnet-ranges)  VPC network, you can't create an allocated range that matches or overlaps with`<IP_ADDRESS>/9`. This range is for  [automatically created subnets](https://cloud.google.com/vpc/docs/vpc#ip-ranges).
- Select a CIDR block that large enough to meet your current and future needs. If you later find that the range isn't sufficient in size,  [expand](https://cloud.google.com/vpc/docs/configure-private-services-access#modify-ip-range)  the range if possible. Although you can assign multiple allocations to a single service producer, Google enforces a quota on the number of IP address ranges that you can allocate, not the size (netmask) of each range.
- Don't reuse the same allocated range for multiple service producers. Although it's possible, doing so can lead to IP address overlap. Each service producer has visibility only into their network and can't know which IP addresses other service producers are using.
- You can only assign one CIDR block to an allocated range when you create the allocation. If you need to  [expand](https://cloud.google.com/vpc/docs/configure-private-services-access#modify-ip-range)  the IP address range, you can't add more blocks to an allocation. Instead, you can create another allocation or recreate the existing one by using a larger block that encompasses the new and existing ranges.

More information on [GCP Regions](https://cloud.google.com/compute/docs/regions-zones/).

#### 5. Service Account
Create a service account that will be used by SDRS. The service account should have proper permissions to publish to
[Pub/Sub topic](https://cloud.google.com/pubsub/docs/access-control) and create [Storage Transfer Service](https://cloud.google.com/storage-transfer/docs/iam-transfer) jobs. The credential of the service account is put in a
 GCS bucket that only the deployment script has access. The [startup script](./mig/scripts/startup.sh), as part of MIG instance creation, gets the credential from the GCS bucket and sets the [GOOGLE_APPLICATION_CREDENTIALS](https://cloud.google.com/docs/authentication/production) environment variable for SDRS docker container.

### SDRS Deployment
The following are instructions to deploy SDRS and click the links for details for each step:
1. Create a [CloudSQL](./cloud-sql/README.md) instance. (Takes about 10-15 minutes). Set [log_bin_trust_function_creators](https://stackoverflow.com/questions/47359508/cant-create-trigger-on-mysql-table-within-google-cloud) to true.

 2. Run [SQL DDL](../sql/retention_schema.sql) to create a database schema in Cloud SQL created above.
 2. Create a [Pub/Sub topic](./pub-sub) for SDRS to publish messages.
 3. Create a [custom image](#custom-image) to be used by MIG.
 4. Launch a [Managed Instance Group cluster](./mig/README.md) (Takes about 5 minutes ). This step
 creates the MIG and deploys SDRS into the MIG.

         Follow the steps section I (subsection 1 through 11) to create a Managed Instance Group.

4. Deploying the [Endpoints configuration](#cloud-endpoints) using the following command.

          gcloud endpoints services deploy openapi.yaml

### SDRS Update
 Update the SDRS application using [MIG Updater](./mig/README.md).

 Follow the steps section II (subsection 1 through 4) to update the version of new software on the existing Managed Instance Group.

> Notes:
>  1. The Managed Instance Group updater does NOT cause a change of Internal Load Balancer Private IP Address or Endpoints configuration
> change.
> 2. The Managed Instance Group Infrastructure is immutable i.e. when you update the MIG with a newer software version the VM instances are
> replaced by the new VM instances running newer software version.
> 3. You can not stop or restart VM instances in a MIG.

## Appendix
### Cloud Endpoints

Cloud Endpoints is a distributed API management system that helps you secure, monitor, analyze, and set quotas on your APIs using the same infrastructure Google uses for its own APIs. Endpoints works with the Extensible Service Proxy (ESP) to provide API management. It provides an API console, hosting, logging, monitoring, and Authenticating API users to help you create, share, maintain, and secure your APIs.

You can view the Endpoints service configuration on the Endpoints > Services page in the GCP Console.

#### OpenAPI Configuration
OpenAPI configuration file, openapi.yaml is based on OpenAPI Specification v2.0.

#### DNS and SSL

 - Using your [own DNS as the name of your Cloud Endpoints
   Service](https://cloud.google.com/endpoints/docs/openapi/verify-domain-name). If you already own a domain name (such as `mycompany.com`), and you
   want to use this domain name as the name of your Cloud Endpoints
   service, you must prove that you are authorized to use the domain.

 - You may need to enable an SSL port for your deployed Endpoints service so that it can serve HTTPS requests. Refer to [Enabling   SSL](https://cloud.google.com/endpoints/docs/openapi/enabling-ssl)   for Cloud Endpoints for details
### Custom Image
A custom CentOS-7 image is created to be used by MIG as the startup script needs to access GCS bucket and run Docker.  The following is the instruction:
1.  CentOS 7 base image used to create a VM

2.  `#sudo yum remove docker` (Remove any prior installations of docker from the VM)

3.  Setup the Docker repository

	a).  Install required packages using the following command `#sudo yum install -y yum-utils device-mapper-persistent-data lvm2`

	b).  Use the following command to setup repository `#sudo yum-config-manager --add-repo`

4.  Install latest version of docker using the following command `#sudo yum install docker-ce`

5.  Start the docker service `#sudo systemctl start docker`

6.  Start the chkconfig service using below command to make sure the service comes up in case the VM restarts `#chkconfig docker on`

7.  Google Cloud SDK is installed on the CentOS 7 image by default.

8.  Via the GCP Cloud Console, shut down the VM

9.  Create an image

	a)  Compute Engine → Images → Create Image → Source (Disk) → Source Disk (VM name you just created) → Create

10.  It would typically take 10 minutes to get the image created.
### Google Project

    gcloud projects create PROJECT_ID

Where PROJECT_ID is the ID for the project you want to create. A project ID must start with a lowercase letter, and can contain only ASCII letters, digits, and hyphens, and must be between 6 and 30 characters.

Each GCP project has:

* A project name, which you provide.
* A project ID, which you can provide or GCP can provide for you.
* A project number, which GCP provides.

Follow the recommended [security best practices](https://cloud.google.com/iam/docs/using-iam-securely) when using Cloud IAM and Google Cloud in general.

* Principle of least privilege
* Rotate your service account keys using the [Cloud IAM service account API](https://cloud.google.com/iam/reference/rest/v1/). You can rotate a key by creating a new key, switching applications to use the new key and then deleting old key.
* Do not delete service accounts that are in use by running instances. This could result in all or parts of your application to fail if you have not transitioned to using an alternative service account first.
* Don’t check in the service account keys into the source code or leave them in the Downloads directory.
* Audit who has the ability to change your Cloud IAM policies on your projects.

repository: jitkasempin/storage-sdrs

repo_name: jitkasempin/storage-sdrs


text:
# meetup-raffle

[![Deploy to Netlify][deploy-image]][deploy-link]

Draw raffle winners at your [Meetup][meetup] event.

[deploy-image]: https://www.netlify.com/img/deploy/button.svg
[deploy-link]:
  https://app.netlify.com/start/deploy?repository=https://github.com/wKovacs64/meetup-raffle
[meetup]: https://www.meetup.com/

license: MIT

repository: omkay/meetup-raffle

gha_language: JavaScript

gha_license_id: MIT

repo_name: omkay/meetup-raffle


text:
# SNEAKER_CRED

SneakerCred utilizes ERC1155 to Manufature 'MyTeamCards', 'MyCareer', & Virtual Currency for Video Games such as 'NBA2K' series. The purpose of this project is to allow game users to be the custodians for their in-game Assets using their Wallet and also able to trade them	on a decentralized exchange.

Tokenization of Sports Assets in Gaming Or
“Tokenized In Game Assets” NBA2K NFT collectibles & Esport exchange Smart Contract

“This is for NBA2K Game participants to have the ability to Trade Sneakers in game for Boost Points in play making actions.
*Ewing only has Nikes but can add Reeboks Under Armour-
UI: in line up screen go to add a shoe, if only shows one brand… Go to your shoe collection
Apply to player + Add More!

Application layer
NFT Shoes +Boosts Points ERC 20 Tokens

“The players will be able to walk their created character into a virtual foot locker and shop for a new pair of kicks in the [Run the Neighborhood] (Game Mode)

3. Technology
Full Stack Ethereum Development
Solidity Smart Contract Architecture ERC 1155
Token Factory libraries “Inheritance”
Web3.Swift ios mobile Ethereum Development

0x Contract Extentions
Dutch Auction

0x multi asset proxy allow multiple assets of an order ex. “selling Boost Packs”

0x instant for in game purchases

Smart Contract Architecture ERC 1155 Solidity &
0x Protocol

Making the player and object that has metadata
Mapping the Struct to the Badges as an Index in storage
Listing the player functionality as a String
Attributes
Player
Position
Points
Badges
Trade
Value

Extract the players sneakers and the associated Boost Power of the shoes as a token class

Boost Points
Player Badges

## Getting Started

http://bit.ly/snkrcred

 ...a little demo

## Deployment

http://bit.ly/snkrcreddemo

## Built With

* [OpenZeppelin] (https://github.com/OpenZeppelin/openzeppelin-solidity)
* [SolidityC.R.U.D] (https://github.com/rob-Hitchens/UnorderedKeySet)
* [Enjin-ERC1155] (https://github.com/enjin/erc-1155)
* [0x Instant] (https://github.com/casmirconsensys/0x-launch-kit)

* [Remix](http://remix.ethereum.org) - The web IDE used
* [Truffle](http://Truffleframework.com) - Development Management
* [Ganache](https://truffleframework.com/docs/ganache/workspaces/the-quickstart-workspace) - Used to generate local blockchain

## Contributing

Please read [CONTRIBUTING.md](https://gist.github.com/PurpleBooth/b24679402957c63ec426) for details on our code of conduct, and the process for submitting pull requests to us.

## Versioning

We use [pragma solidity ^0.5.0](https://solidity.readthedocs.io/en/v0.5.3/layout-of-source-files.html) for versioning. For ABI Encoding, see the [ABIEncoderV2](https://github.com/ethereum/solidity/issues/3379).

## Authors

* **Casmir Patterson** - *Initial work* - [SneakerCred](https://github.com/casmirconsensys/SneakerCred)

See also the list of contracts [cryptokitties](https://github.com/dapperlabs/cryptokitties-bounty/blob/master/contracts/KittyCore.sol) who inspired this project.

## License

This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details

## Acknowledgments

* Hat tip to Rob Hutchins - A Reusable Implementation of the popular storage pattern for Ethereum
* Inspiration - NBA2K 'MyTeamCards'
* [Run the Neighborhood] “The players will be able to walk their created character into a 'Virtual Foot Locker' and shop for a new pair of kicks in the  (NBA2K Game Mode)"

repository: casmirconsensys/SneakerCred

repo_name: casmirconsensys/SneakerCred


text:
This directory contains the script to preprocess the WikiCite dataset for "Summary Cloze: A New Task for Content Selection in Topic-Focused Summarization."

First, run the setup script under the `data/wikicite` directory.
Then, run the `setup.sh` script to compute the ROUGE-based heuristic extractive labels for the dataset.
The processing speed is somewhat slow, so it may take several hours to process the data.
Alternatively, the preprocessed data can be downloaded here:
train,
valid,
test.

repository: CogComp/summary-cloze

repo_name: CogComp/summary-cloze