Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Baseline code to query Spanner using DynamoDB queries #3

Merged
merged 60 commits into from
Mar 17, 2021
Merged
Show file tree
Hide file tree
Changes from 48 commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
b230861
Baseline code to query Spanner using DynamoDB queries
Jul 12, 2020
0dd22fc
readme file
ankitmalikg2 Jul 20, 2020
21565f9
DYN-40: integration testing framework added
ankitmalikg2 Jul 21, 2020
bcfb665
Merge pull request #4 from cldcvr/DYN-40
ankitmalikg2 Jul 30, 2020
1b1e61c
DYN-39: added base functions for output change
ankitmalikg2 Aug 13, 2020
29e8bd7
DYN-41: GetItem API added
ankitmalikg2 Jul 27, 2020
a0384aa
DYN-41 test cases imporved
ankitmalikg2 Jul 30, 2020
786798b
DYN-41: getItem API output & test case changed
ankitmalikg2 Aug 13, 2020
23f4f56
Merge pull request #7 from cldcvr/DYN-39
ankitmalikg2 Aug 18, 2020
0e91cce
Merge pull request #5 from cldcvr/DYN-41
ankitmalikg2 Aug 18, 2020
d12104f
DYN-43: BatchGet api input and output changes done
ankitmalikg2 Aug 15, 2020
aa1d343
DYN-43: test cases added & end-point correction
ankitmalikg2 Aug 15, 2020
bacea2d
Merge pull request #10 from cldcvr/DYN-39
ankitmalikg2 Aug 18, 2020
477a37c
DYN-41: Query api change
ankitmalikg2 Aug 4, 2020
a6cfb7c
DYN-42: test cases added
ankitmalikg2 Aug 13, 2020
5220306
DYN-42: query api output & testcases changed
ankitmalikg2 Aug 13, 2020
10cb240
DYN-44: scan input & output changed
ankitmalikg2 Aug 16, 2020
ee3e2cd
DYN-44: corrected url & added test cases
ankitmalikg2 Aug 16, 2020
4ca2fae
Merge pull request #6 from cldcvr/DYN-42
ankitmalikg2 Aug 18, 2020
c2d9ac2
DYN-31: input & output chnages for UpdateItem
ankitmalikg2 Aug 17, 2020
7a9a00e
DYN-31: Put API input & output changes
ankitmalikg2 Aug 17, 2020
e9bb6d0
DYN-31: test cases & output change for Update
ankitmalikg2 Aug 19, 2020
37cee86
DYN-31: removed commented code for test
ankitmalikg2 Aug 19, 2020
4471789
Merge pull request #11 from cldcvr/DYN-31
ankitmalikg2 Aug 24, 2020
110f51d
DYN-47: DeleteItem API implementation & test cases
ankitmalikg2 Aug 19, 2020
ee36367
DYN-48: BatchWriteItem API input changes
ankitmalikg2 Aug 21, 2020
6146bdf
DYN-48: BatchWriteItem API test cases added
ankitmalikg2 Aug 21, 2020
95262d6
DYN-48: test cases for spanner has been corrected
ankitmalikg2 Aug 21, 2020
1e2f6d8
DYN-47: Delete API test cases
ankitmalikg2 Aug 24, 2020
4d5bdd7
Merge pull request #12 from cldcvr/DYN-47
ankitmalikg2 Aug 24, 2020
ec10aa6
corrected 1 test case
ankitmalikg2 Aug 24, 2020
40a00b4
DYN-33: initial test data has been added
ankitmalikg2 Aug 25, 2020
f548425
DYN-51: imporved readme file
ankitmalikg2 Sep 2, 2020
82bf44b
utils: unit test added
ankitmalikg2 Sep 11, 2020
d6ad2e4
config_test added
ankitmalikg2 Sep 11, 2020
0fbf2c1
condition test cases added
ankitmalikg2 Sep 15, 2020
6f4c327
services test cases added
ankitmalikg2 Sep 15, 2020
59c3251
test case for services added
ankitmalikg2 Sep 17, 2020
121289d
Merge pull request #14 from cldcvr/DYN-51
ankitmalikg2 Oct 12, 2020
e4cc49a
Merge pull request #15 from cldcvr/DYN-34
ankitmalikg2 Oct 12, 2020
f115448
CCI03-52 : license header added
ankitmalikg2 Oct 12, 2020
07b5d95
CCI03-52: package comments added
ankitmalikg2 Oct 12, 2020
7d0bcde
Merge pull request #16 from cldcvr/CCI03-52
ankitmalikg2 Oct 15, 2020
5172b25
Update README.md
ankitmalikg2 Oct 15, 2020
d599f4a
CCI03-53: readme file & config file improved
ankitmalikg2 Oct 15, 2020
8bb6225
prod config file improved
ankitmalikg2 Oct 15, 2020
11c3b3a
Merge pull request #17 from cldcvr/CCI03-53
ankitmalikg2 Oct 15, 2020
7b1d3b6
added proper space in readme
ankitmalikg2 Oct 15, 2020
6a5cfbb
fix : issues related linting fixed
ankitmalikg2 Nov 17, 2020
fe7d852
Merge pull request #18 from cldcvr/fix/linting_issues
ankitmalikg2 Nov 17, 2020
b6b892a
fix: linting issues for log and model fixed
ankitmalikg2 Nov 17, 2020
84d4545
Merge pull request #19 from cldcvr/fix/linting_issues
ankitmalikg2 Nov 18, 2020
02968b8
fix: logger_test linting issue fixed
ankitmalikg2 Nov 18, 2020
b39d50a
Merge pull request #20 from cldcvr/fix/linting_issues
ankitmalikg2 Dec 21, 2020
9117213
fix: logger_test linting issue fixed
ankitmalikg2 Nov 18, 2020
24b493d
Merge pull request #21 from cldcvr/fix/linting_issues
ankitmalikg2 Dec 21, 2020
5218d65
updated README.md and configured integration test to run setup and cl…
sauravcld Jan 15, 2021
275f5e3
updated config to contain description
sauravcld Jan 18, 2021
2abde1d
Fix: Typos
sauravcld Jan 20, 2021
95cdd76
integration test: to check ddl table updated correctly before executi…
sauravcld Feb 1, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

FROM golang:1.12


# Set the Current Working Directory inside the container
WORKDIR /go/src/db-driver

# Force the go compiler to use modules
ENV GO111MODULE=on

# We want to populate the module cache based on the go.{mod,sum} files.
COPY go.mod .
COPY go.sum .

#This is the 'magic' step that will download all the dependencies that are specified in
# the go.mod and go.sum file.
# Because of how the layer caching system works in Docker, the go mod download
# command will _ only_ be re-run when the go.mod or go.sum file change
# (or when we add another docker instruction this line)
RUN go mod download

# Copy everything from the current directory to the PWD(Present Working Directory) inside the container
COPY . .

# Set active environment
ARG ACTIVE_ENV
ENV ACTIVE_ENV ${ACTIVE_ENV}

# Download all the dependencies
# https://stackoverflow.com/questions/28031603/what-do-three-dots-mean-in-go-command-line-invocations
#RUN go get -d -v ./...

# Install the package
RUN go install -v ./...

# Run the executable
CMD ["db-driver"]
183 changes: 182 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,185 @@
[![Join the chat at
https://gitter.im/cloudspannerecosystem/dynamodb-adapter](https://badges.gitter.im/cloudspannerecosystem/dynamodb-adapter.svg)](https://gitter.im/cloudspannerecosystem/dynamodb-adapter?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

Work in progress -- please check back later!

## Introduction
Dynamodb-adapter is an API tool that translates AWS DynamoDB queries to Cloud Spanner equivalent queries and runs those queries on Cloud Spanner. By running this project locally or in the cloud, this would work seamlessly.

Additionally, it also supports primary and secondary indexes in a similar way as DynamoDB.

It will be helpful for moving to Cloud Spanner from DynamoDB environment without changing the code for DynamoDB queries. The APIs created by this project can be directly consumed where DynamoDB queries are used in your application.

This project requires two tables to store metadata and configuration for the project:
* dynamodb_adapter_table_ddl (for meta data of all tables)
* dynamodb_adapter_config_manager (for pubsub configuration)

It supports two mode -
* Production
* Staging

## Usage
Follow the given steps to setup the project and generate the apis.

### 1. Creation of the required configuration tables in Spanner
#### Table: dynamodb_adapter_table_ddl
This table will be used to store the metadata for other tables. It will be used at the time of initiation of project to create a map for all the columns names present in Spanner tables with the columns of tables present in DynamoDB. This mapping is required by because dynamoDB supports the special characters in column names while spanner does not support special characters other than underscores(_).
For more: [Spanner Naming Conventions](https://cloud.google.com/spanner/docs/data-definition-language#naming_conventions)

```
CREATE TABLE
dynamodb_adapter_table_ddl
(
column STRING(MAX),
tableName STRING(MAX),
dataType STRING(MAX),
originalColumn STRING(MAX),
) PRIMARY KEY (tableName, column)
```

Add the meta data of all the tables in the similar way as shown below.

![dynamodb_adapter_table_ddl sample data](images/config_spanner.png)

#### Table: dynamodb_adapter_config_manager
This table will be used to store the configuration info for publishing the data in Pub/Sub topic for other processes on change of data. It will be used to do some additional operation required on the change of data in tables. It can trigger New and Old data on given Pub/Sub topic.

```
CREATE TABLE
dynamodb_adapter_config_manager
(
tableName STRING(MAX),
config STRING(MAX),
cronTime STRING(MAX),
enabledStream STRING(MAX),
pubsubTopic STRING(MAX),
uniqueValue STRING(MAX),
) PRIMARY KEY (tableName)
```


### 2. Creation for configuration files
There are two folders in [config-files](./config-files).
* **production** : It will be used to store the config files related to Production Environment.
* **staging** : It will be used to store the config files related to Production Environment.
sauravcld marked this conversation as resolved.
Show resolved Hide resolved

Add the configuration in the given files:
#### config.{env}.json
| Key | Used For |
| ------ | ------ |
| GOOGLE_PROJECT_ID | Your Google Project ID |
| SPANNER_DB | Your Spanner Database Name |

For example:
```
{
"GOOGLE_PROJECT_ID" : "first-project",
"SPANNER_DB" : "test-db"
}
```

#### spanner.{env}.json
It is a mapping file for table name with instance id. It will be helpful to query data on particular instance.
The instance-id of all tables should be stored in this file in the following format:
"TableName" : "instance-id"

For example:

```
{
"dynamodb_adapter_table_ddl": "spanner-2 ",
"dynamodb_adapter_config_manager": "spanner-2",
"tableName1": "spanner-1",
"tableName2": "spanner-1"
...
...
}
```

#### tables.{env}.json
ankitmalikg2 marked this conversation as resolved.
Show resolved Hide resolved
All table's primary key, columns, index information will be stored here.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I can tell, the current version only supports the following DynamoDB data types:

  • S (String)
  • N (Number)
  • BOOL

Could that be documented here?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rosspatil who do think about this?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Captured in Issue #14


| Key | Used For |
| ------ | ------ |
| tableName | table name present in dynamoDb |
| partitionKey | Primary key |
| sortKey| Sorting key |
| attributeTypes | Column names and type present |
| indices | indexes present in the table |


For example:

```
{
"tableName":{
"partitionKey":"primary key or Partition key",
"sortKey": "sorting key of dynamoDB adapter",
"attributeTypes": {
"ColumnName1": "N",
"ColumnName2": "S"
},
"indices": {
"indexName1": {
"sortKey": "sort key for indexName1",
"partitionKey": "partition key for indexName1"
}
}
},
.....
.....
}
```


### 3. Creation of rice-box.go file

##### install rice package
This package is required to load the config files. This is required in the first step of the running dynamoDB-adapter.

```
go get github.com/GeertJohan/go.rice
go get github.com/GeertJohan/go.rice/rice
```
##### run command for creating the file.
This is required to increase the performance when any config file is changed so that configuration files can be loaded directly from go file.
```
rice embed-go
ankitmalikg2 marked this conversation as resolved.
Show resolved Hide resolved
```

### 4. Run
* Setup GCP project on **gcloud cli**
ankitmalikg2 marked this conversation as resolved.
Show resolved Hide resolved

If **gcloud cli** is not installed then firstly install **gcloud cli** [reference](https://cloud.google.com/sdk/docs/install)
Then run the following commands for setting up the project which has Cloud Spanner Database.
```
gcloud auth login
gcloud projects list
gcloud config set project `PROJECT NAME`
```
[Reference](https://cloud.google.com/sdk/gcloud/reference/auth/login) for `gcloud auth login`

[Reference](https://cloud.google.com/sdk/gcloud/reference/projects/list) for `gcloud auth login`

[Reference](https://cloud.google.com/sdk/gcloud/reference/config/set) for `gcloud auth login`

* Run for **staging**
```
go run main.go
```
* Run for **Production**
```
export ACTIVE_ENV=PRODUCTION
go run main.go
```

## Starting Process
* Step 1: DynamoDB-adapter will load the configuration according the Environment Variable *ACTIVE_ENV*
* Step 2: DynamoDB-adapter will initialize all the connections for all the instances so that it doesn't need to start the connection again and again for every request.
* Step 3: DynamoDB-adapter will parse the data inside dynamodb_adapter_table_ddl table and will store in ram for faster access of data.
* Step 4: DynamoDB-adapter will parse the dynamodb_adapter_config_manager table then will load it in ram. It will check for every 1 min if data has been changed in this table or not. If data is changed then It will update the data for this in ram.
* Step 5: After all these steps, DynamoDB-adapter will start the APIs which are similar to dynamodb APIs.


## API Documentation
This is can be imported in Postman or can be used for Swagger UI.
You can get open-api-spec file here [here](https://github.com/cldcvr/dynamodb-adapter/wiki/Open-API-Spec)
30 changes: 30 additions & 0 deletions api/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package api implements the apis versions
// Different api version can be grouped here
package api

import (
v1 "github.com/cloudspannerecosystem/dynamodb-adapter/api/v1"

"github.com/gin-gonic/gin"
)

// InitAPI - initialize api
func InitAPI(g *gin.Engine) {
r := g.Group("/v1")
v1.InitDBAPI(r)

}
Loading